T-gnus 6.15.11 revision 00. t-gnus-6_15_11-00
authoryamaoka <yamaoka>
Sun, 12 Jan 2003 14:35:43 +0000 (14:35 +0000)
committeryamaoka <yamaoka>
Sun, 12 Jan 2003 14:35:43 +0000 (14:35 +0000)
48 files changed:
ChangeLog
GNUS-NEWS
README.T-gnus
README.semi
README.semi.ja
etc/gnus/preview.xbm [new file with mode: 0644]
etc/gnus/preview.xpm [new file with mode: 0644]
etc/gnus/receipt.xpm [new file with mode: 0644]
lisp/ChangeLog
lisp/deuglify.el
lisp/gnus-agent.el
lisp/gnus-art.el
lisp/gnus-cite.el
lisp/gnus-fun.el
lisp/gnus-group.el
lisp/gnus-int.el
lisp/gnus-msg.el
lisp/gnus-score.el
lisp/gnus-sieve.el
lisp/gnus-spec.el
lisp/gnus-srvr.el
lisp/gnus-sum.el
lisp/gnus-vers.el
lisp/gnus.el
lisp/lpath.el
lisp/mail-source.el
lisp/message.el
lisp/mm-decode.el
lisp/mm-url.el
lisp/mm-util.el
lisp/mml.el
lisp/nndraft.el
lisp/nnheader.el
lisp/nnmail.el
lisp/nnmaildir.el
lisp/nnrss.el
lisp/nntp.el
lisp/nnweb.el
lisp/spam-stat.el
lisp/spam.el
texi/ChangeLog
texi/booklet.tex
texi/gnus-ja.texi
texi/gnus.texi
texi/gnusref.tex
texi/message-ja.texi
texi/message.texi
texi/refcard.tex

index 5252c70..e6b09e2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,6 @@
-2003-01-11  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+2003-01-12  Katsumi Yamaoka  <yamaoka@jpl.org>
 
 
-       * lisp/gnus-start.el (gnus-read-newsrc-el-file): Make sure that
-       the newsrc-alist is initialized properly.
+       * lisp/gnus-vers.el: T-gnus 6.15.11 revision 00.
 
 2003-01-11  Katsumi Yamaoka  <yamaoka@jpl.org>
 
 
 2003-01-11  Katsumi Yamaoka  <yamaoka@jpl.org>
 
        * lisp/message.el (message-tool-bar-map): Commented out MIME-Edit
        buttons.
 
        * lisp/message.el (message-tool-bar-map): Commented out MIME-Edit
        buttons.
 
-2003-01-10  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+2003-01-09  Simon Josefsson  <jas@extundo.com>
 
 
-       * lisp/gnus-start.el (gnus-read-newsrc-el-file): Make sure the
-       .eld file exists.
+       * etc/gnus/preview.xpm: Add.
+
+2003-01-06  Simon Josefsson  <jas@extundo.com>
+
+       * etc/gnus/receipt.xpm: Add.
+
+2003-01-10  Jesper Harder  <harder@ifa.au.dk>
+
+       * etc/gnus/preview.xbm: Add.
 
 2003-01-09  Katsumi Yamaoka  <yamaoka@jpl.org>
 
 
 2003-01-09  Katsumi Yamaoka  <yamaoka@jpl.org>
 
 
 2003-01-05  Katsumi Yamaoka  <yamaoka@jpl.org>
 
 
 2003-01-05  Katsumi Yamaoka  <yamaoka@jpl.org>
 
+       * etc/gnus/gnus.xpm (oort): Make the color replaceable.
+
+2003-01-05  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * lisp/gnus-vers.el: T-gnus 6.15.11 (quimby) revision 00.
+
+2003-01-05  Katsumi Yamaoka  <yamaoka@jpl.org>
+
        * lisp/gnus-vers.el: T-gnus 6.15.10 revision 00.
 
 2003-01-03  Katsumi Yamaoka  <yamaoka@jpl.org>
        * lisp/gnus-vers.el: T-gnus 6.15.10 revision 00.
 
 2003-01-03  Katsumi Yamaoka  <yamaoka@jpl.org>
index a13f4ef..3bf0e30 100644 (file)
--- a/GNUS-NEWS
+++ b/GNUS-NEWS
@@ -8,6 +8,9 @@ For older news, see Gnus info node "New Features".
 \f
 * Changes in Oort Gnus
 
 \f
 * Changes in Oort Gnus
 
+** References and X-Draft-Headers are no longer generated when you
+   start composing messages.
+
 ** Improved anti-speam features.
 
 ** Easy inclusion of X-Faces headers.
 ** Improved anti-speam features.
 
 ** Easy inclusion of X-Faces headers.
index 861d369..52bb09b 100644 (file)
@@ -1,6 +1,6 @@
 ========================================================================
 Codename:      T-gnus
 ========================================================================
 Codename:      T-gnus
-Branch Tag:    t-gnus-6_15
+Branch Tag:    t-gnus-6_15-quimby
 Branch Status: Develop, Synchronize with Oort Gnus
 Branch Goal:   Implement latest features of gnus and offline features
                Use Gnus in Offline status.
 Branch Status: Develop, Synchronize with Oort Gnus
 Branch Goal:   Implement latest features of gnus and offline features
                Use Gnus in Offline status.
@@ -33,5 +33,5 @@ NEWS:
 
 * T-gnus 6.15 - this is based on Oort Gnus.
 
 
 * T-gnus 6.15 - this is based on Oort Gnus.
 
-  The latest T-gnus is T-gnus 6.15.10 (based on Oort Gnus 0.10).  It
+  The latest T-gnus is T-gnus 6.15.11 (based on Oort Gnus 0.11).  It
   requires SEMI 1.14, FLIM 1.14, and APEL 10.0 or later.
   requires SEMI 1.14, FLIM 1.14, and APEL 10.0 or later.
index b5ca69b..847ab4f 100644 (file)
@@ -4,7 +4,7 @@ What is T-gnus?
 ===============
 
   T-gnus is an improvement of Gnus with SEMI's MIME feature. T-gnus
 ===============
 
   T-gnus is an improvement of Gnus with SEMI's MIME feature. T-gnus
-6.15 is based on Oort Gnus v0.10. SEMI may stand for "SEMI is Emacs
+6.15 is based on Oort Gnus v0.11. SEMI may stand for "SEMI is Emacs
 MIME Interface" and is developped to provide an easy interfaces for
 users to handle MIME message structures. For further information,
 refer to REASME.en of SEMI.
 MIME Interface" and is developped to provide an easy interfaces for
 users to handle MIME message structures. For further information,
 refer to REASME.en of SEMI.
@@ -39,7 +39,7 @@ How to get? (via CVS)
 (1) checkout
 
     % cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/root \
 (1) checkout
 
     % cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/root \
-       checkout -r t-gnus-6_15 gnus
+       checkout -r t-gnus-6_15-quimby gnus
 
 (2) compile
 
 
 (2) compile
 
@@ -49,7 +49,7 @@ How to get? (via CVS)
 
 (3) update
 
 
 (3) update
 
-    % cvs update -r t-gnus-6_15 gnus
+    % cvs update -r t-gnus-6_15-quimby gnus
 
 Major tags are following:
 
 
 Major tags are following:
 
index f119198..943f345 100644 (file)
@@ -4,7 +4,7 @@ T-gnus \e$B$H$O!)\e(B
 =============
 
   T-gnus \e$B$O!"\e(BSEMI \e$B$rMxMQ$7$F\e(B Gnus \e$B$K\e(B MIME \e$B5!G=$rDI2C$9$k$b$N$G$9!#\e(B
 =============
 
   T-gnus \e$B$O!"\e(BSEMI \e$B$rMxMQ$7$F\e(B Gnus \e$B$K\e(B MIME \e$B5!G=$rDI2C$9$k$b$N$G$9!#\e(B
-T-gnus 6.15 \e$B$O\e(B Oort Gnus v0.10 \e$B$r%Y!<%9$K$7$F$$$^$9!#\e(BSEMI \e$B$O\e(B Emacs \e$B$G\e(B
+T-gnus 6.15 \e$B$O\e(B Oort Gnus v0.11 \e$B$r%Y!<%9$K$7$F$$$^$9!#\e(BSEMI \e$B$O\e(B Emacs \e$B$G\e(B
 MIME \e$B$r;H$($k$h$&$K$9$k$b$N$G!"\e(BMIME message \e$B$N9=J8$N9=B$$HMxMQ<T$N4V$r\e(B
 \e$B$D$J$0%$%s%?!<%U%'!<%9$rDs6!$7$^$9!#>\$7$/$O!"\e(BSEMI \e$B$N\e(B README.en \e$B$r;2>H\e(B
 \e$B$7$F$/$@$5$$!#\e(B
 MIME \e$B$r;H$($k$h$&$K$9$k$b$N$G!"\e(BMIME message \e$B$N9=J8$N9=B$$HMxMQ<T$N4V$r\e(B
 \e$B$D$J$0%$%s%?!<%U%'!<%9$rDs6!$7$^$9!#>\$7$/$O!"\e(BSEMI \e$B$N\e(B README.en \e$B$r;2>H\e(B
 \e$B$7$F$/$@$5$$!#\e(B
@@ -40,7 +40,7 @@ http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/
 (1) checkout
 
     % cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/root \
 (1) checkout
 
     % cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/root \
-       checkout -r t-gnus-6_15 gnus
+       checkout -r t-gnus-6_15-quimby gnus
 
 (2) compile
 
 
 (2) compile
 
@@ -50,7 +50,7 @@ http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/
 
 (3) update
 
 
 (3) update
 
-    % cvs update -r t-gnus-6_15 gnus
+    % cvs update -r t-gnus-6_15-quimby gnus
 
 \e$B<g$J%?%0$O0J2<$N$h$&$K$J$C$F$$$^$9\e(B:
 
 
 \e$B<g$J%?%0$O0J2<$N$h$&$K$J$C$F$$$^$9\e(B:
 
diff --git a/etc/gnus/preview.xbm b/etc/gnus/preview.xbm
new file mode 100644 (file)
index 0000000..a42e153
--- /dev/null
@@ -0,0 +1,10 @@
+#define preview_width 24
+#define preview_height 24
+static char preview_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0xc0,0x03,0x00,0x3e,0x06,0xf0,0x03,0x04,0x08,0x00,0x0a,0x78,0x00,0x09,
+ 0x88,0xf9,0x08,0x10,0xc6,0x10,0x10,0x3a,0x13,0x10,0x06,0x15,0x20,0x02,0x29,
+ 0x20,0x02,0x31,0x20,0xad,0x0f,0x40,0xf9,0x03,0xc0,0xb8,0x07,0x80,0x07,0x0e,
+ 0x80,0x01,0x1c,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x00,
+ 0x00,0x00,0x39,0x00,0x00,0x00,0x08,0xc0,0x12,0x42,0x00,0x00,0x00,0x00,0x38,
+ 0x82,0x18,0x08,0x00,0x00,0x00 };
diff --git a/etc/gnus/preview.xpm b/etc/gnus/preview.xpm
new file mode 100644 (file)
index 0000000..f5743f9
--- /dev/null
@@ -0,0 +1,33 @@
+/* XPM */
+static char *prev1[]={
+"24 24 6 1",
+". c None",
+"# c #000000",
+"d c #46463e",
+"a c #676663",
+"c c #a8a7a3",
+"b c #ebeae4",
+"........................",
+"........................",
+"........................",
+"........................",
+"........................",
+"..............####......",
+".........#####abbc#.....",
+"....#####acbbbbbbc#.....",
+"...#acbbbbbbbbbbacc#....",
+"...#baabbbbbbbbcacb#....",
+"...#cbcaabbd##dacbb#....",
+"....#bbbccdcbbcdabbc#...",
+"....#bbbbdccaaccdacb#...",
+"....#cbbb#abbbbb#bac#...",
+".....#bbb#cbbbbc#bbac#..",
+".....#bbbdcbbbbddbbc##..",
+".....#cbccdcbbd#####....",
+"......#babbd##dd##......",
+"......#acbc###.####.....",
+"......#aa##......###....",
+".......##.........###...",
+"...................##...",
+"........................",
+"........................"};
diff --git a/etc/gnus/receipt.xpm b/etc/gnus/receipt.xpm
new file mode 100644 (file)
index 0000000..18caaf1
--- /dev/null
@@ -0,0 +1,32 @@
+/* XPM */
+static char * receipt_xpm[] = {
+"24 24 5 1",
+"      c None",
+".     c #FFFFFFFFFFFF",
+"X     c #676766666363",
+"o     c #FFFF00000000",
+"O     c #AEAE3E3E4848",
+"                        ",
+"                        ",
+"                   ..   ",
+"                    .   ",
+"                     .  ",
+"                     .  ",
+"                   ..   ",
+"           Xooo  ..     ",
+"      Xoooooooo..       ",
+" Xoooooooooooooo  ...   ",
+" oooooooooooOOoo .      ",
+" ooooooooooOOOOo.       ",
+"  oooooooooOO...o       ",
+"  ooooooooooOOooo       ",
+"  ooooooooooooooo       ",
+"   ooooooooooooooo      ",
+"   oooooooooooooo       ",
+"   ooooooooooo          ",
+"    ooooooo             ",
+"    oooo                ",
+"    oo                  ",
+"                        ",
+"                        ",
+"                        "};
index 2ef440a..e6f6717 100644 (file)
@@ -1,3 +1,479 @@
+2003-01-12 13:46:20 Lars Magne Ingebrigtsen <lars@ingebrigtsen.no>
+
+       * gnus.el: Oort Gnus v0.11 is released.
+
+2003-01-12  Jesper Harder  <harder@ifa.au.dk>
+
+       * message.el (message-fetch-reply-field): Narrow to headers.
+
+       * gnus-msg.el (gnus-inews-do-gcc): Don't try to mark GCC's as read
+       if Gnus isn't alive.
+
+2002-01-11  Kevin Greiner  <kgreiner@xpediantsolutions.com>
+
+       * gnus-agent.el (gnus-agent-fetch-group-1): Remove downloadable
+       marks from articles that are already stored in the agent.
+       (gnus-agent-backup-overview-buffer): New debug tool.  Creates a
+       backup copy of an invalid .overview file for later analysis.
+       
+2003-01-12  Gregorio Gervasio, Jr.  <gtgj@pacbell.net>
+
+       * gnus-sum.el (gnus-summary-exit): Reverse change to make group
+       exit work with two frames.
+
+2003-01-11  Fran\e,Ag\e(Bois-David Collin  <Francois-David.Collin@wanadoo.fr>
+
+       * message.el (message-forward-make-body): Use mule4.
+
+2003-01-11  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * message.el (message-mode-map): Move wide-reply command.
+
+2003-01-10  Reiner Steib  <Reiner.Steib@gmx.de>
+
+       * deuglify.el (gnus-outlook-deuglify-attrib-verb-regexp): Added
+       castellano.
+       (gnus-outlook-display-hook): New variable.
+       (gnus-outlook-display-article-buffer): New function.
+       (gnus-outlook-unwrap-lines, gnus-outlook-repair-attribution)
+       (gnus-outlook-deuglify-article): Made them interactive and added
+       optional arg.  Use `g-o-d-a-b'.
+       (gnus-article-outlook-deuglify-article): Use `g-o-d-a-b'.
+
+       * gnus-sum.el: Added autoloads.
+       (gnus-summary-mode-map): Added gnus-summary-wash-deuglify-map.
+       (gnus-summary-make-menu-bar): Added "(Outlook) Deuglify" menu.
+
+2003-01-11  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-art.el (gnus-display-mime): Use the mime emulation
+       variable. 
+
+       * gnus-sum.el (gnus-article-emulate-mime): New variable.
+
+       * gnus-start.el (gnus-read-newsrc-el-file): Make sure that the
+       newsrc-alist is initialized properly.
+
+       * mail-source.el (mail-sources): Autoload.
+
+       * gnus-sum.el (gnus-summary-make-false-root-always): Default to
+       nil.
+
+       * gnus-msg.el (gnus-configure-posting-styles): Make sure we don't
+       insert two newlines.
+
+       * message.el (message-check-news-header-syntax): Compute the
+       header length correctly.
+
+2002-01-10  Kevin Greiner  <kgreiner@xpediantsolutions.com>
+
+       * gnus-agent.el (gnus-agent-expire): Do not remove article from
+       alist when keeping fetched article file.
+       (gnus-agent-retrieve-headers): When parsing response for article
+       numbers, use the same algorithm as gnus-agent-braid-nov to protect
+       against garbage in the server's response.
+
+       * gnus-int.el (gnus-request-expire-articles,
+       gnus-request-move-article): Only expire when the group's server
+       has been agentized.
+
+2003-01-10  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-cite.el (gnus-cite-delete-overlays): Protect against
+       errors when deleting overlays.
+
+       * gnus-score.el (gnus-score-followup): Allow tracing.
+
+       * gnus-art.el (gnus-treat-display-face): New variable.
+       (article-display-face): New command.
+
+       * gnus-fun.el (gnus-face-from-file): New function.
+       (gnus-convert-face-to-png): Ditto.
+
+       * gnus-art.el (gnus-ignored-headers): Added Face.
+
+2003-01-10  Simon Josefsson  <jas@extundo.com>
+
+       * nndraft.el (nndraft-request-group): Avoid crash in
+       directory-files when draft directory doesn't exists.
+
+       * gnus-sum.el (gnus-select-article-hook): Add :option.
+
+2003-01-10  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * spam.el (spam-use-stat): new variable
+       (spam-group-spam-processor-stat-p) 
+       (spam-group-ham-processor-stat-p): new convenience functions
+       (spam-summary-prepare-exit): add spam/ham processors to sequence
+       (spam-list-of-checks): add spam-use-stat to list of checks
+       (spam-split): conditionally load the spam-stat tables
+       (spam-stat-register-spam-routine, spam-stat-register-ham-routine,
+       spam-check-ifile): new functions
+
+       * spam-stat.el (spam-stat): typo fix
+       (spam-stat-install-hooks): new variable
+       (spam-stat-split-fancy-spam-group): added documentation clarification
+       (spam-stat-split-fancy-spam-threshhold): new variable
+       (spam-stat-install-hooks): make hooks conditional
+       (spam-stat-split-fancy): use spam-stat-split-fancy-spam-threshhold
+
+       * gnus.el (gnus-group-ham-exit-processor-stat, spam-process): add
+       spam-stat ham/spam processor symbols
+
+2003-01-10  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-start.el (gnus-read-newsrc-el-file): Make sure the .eld
+       file exists.
+
+2003-01-10  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-sum.el (gnus-summary-read-group-1): Don't select first
+       undownloaded/downloadable only when unplugged.
+
+2003-01-10  Jesper Harder  <harder@ifa.au.dk>
+
+       * gnus-srvr.el (gnus-browse-foreign-server): Optimize inner loop.
+
+2003-01-09  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * spam.el (spam-check-ifile): fixed call-process-region to use the
+       db parameter only if it's set
+       (spam-ifile-register-with-ifile): ditto
+
+2003-01-09  Alex Schroeder  <alex@emacswiki.org>
+
+       * spam-stat.el (spam-stat-save): Set spam-stat-ngood and
+       spam-stat-nbad before creating the hash table.
+       (spam-stat-reset): Set spam-stat-ngood and spam-stat-nbad to 0.
+       Changed copyright statement to FSF.
+
+2002-01-09  Kevin Greiner  <kgreiner@xpediantsolutions.com>
+
+       * gnus-agent.el (gnus-agent-catchup): Do not mark cached nor
+       processable articles as read.
+       (gnus-agent-summary-fetch-series): Remove processable and
+       downloadable marks on all downloaded articles in the series.
+
+       * nntp.el (nntp-report): Throw error after reporting the problem.
+       (nntp-accept-process-output): Corrected error check to report an
+       error when the process is nil.
+
+2003-01-09  Simon Josefsson  <jas@extundo.com>
+
+       * message.el (message-tool-bar-map): Add preview.
+
+2003-01-09  Jesper Harder  <harder@ifa.au.dk>
+
+       * mml.el (mml-preview): Get rid of MIME handles and buffers after
+       previewing.
+
+2003-01-08  Paul Jarc  <prj@po.cwru.edu>
+
+       * nnmaildir.el (nnmaildir--grp-add-art): Fix wrong-type-argument
+       bug when the (n+1)th article to be added to a group has a smaller
+       number than the n articles already added.
+
+2003-01-08  Jesper Harder  <harder@ifa.au.dk>
+
+       * message.el (message-mode-field-menu): Use backquote.
+
+2003-01-08  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * spam.el: fixed the BBDB autoloads again, using
+       bbdb-search-simple now (which is not a macro, thank god)
+
+       * lpath.el (bbdb-search): removed function from maybe-fbind list
+
+       * gnus.el (ham-process-destination): added new parameter for
+       destination of ham articles found in spam groups at summary exit
+
+       * spam.el (spam-get-ifile-database-parameter): use spam-ifile-database-path
+       (spam-check-ifile, spam-ifile-register-with-ifile): use spam-get-ifile-database-parameter
+       (spam-ifile-database-path): added new parameter for ifile's database
+       (spam-move-spam-nonspam-groups-only): new parameter to determine
+       if spam should be moved from all groups or only some
+       (spam-summary-prepare-exit): fixed logic to use
+       spam-move-spam-nonspam-groups-only when deciding to invoke
+       spam-mark-spam-as-expired-and-move-routine; always invoke that
+       routine after the spam has been expired-or-moved in case there's
+       some spam left over; use spam-ham-move-routine in spam groups
+       (spam-ham-move-routine): new function to move ham articles to the
+       ham-process-destinations group parameter
+
+2003-01-08  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-spec.el (gnus-parse-complex-format): %~ => ~*.
+
+       * gnus-agent.el (gnus-agent-fetch-selected-article): Use
+       gnus-summary-update-article-line.
+
+2003-01-08  Simon Josefsson  <jas@extundo.com>
+
+       * nnmail.el (nnmail-expiry-target-group): Request group, create it
+       not successful.
+
+2003-01-08  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * lpath.el (bbdb-records): Fbind it for both Emacs and XEmacs.
+
+2003-01-07  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * spam.el (spam-check-ifile): fixed the spam-ifile-all-categories
+       logic, finally
+
+2003-01-08  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-spec.el (gnus-parse-format): %C is a complex format.
+       (gnus-parse-format): Change to %~.
+
+       * message.el (message-generate-headers): Don't generate optional
+       empty headers.
+
+2003-01-07  Reiner Steib  <Reiner.Steib@gmx.de>
+
+       * message.el (message-cross-post-default)
+       (message-cross-post-note-function, message-shoot-gnksa-feet)
+       (message-strip-subject-trailing-was, message-change-subject)
+       (message-mark-insert-file, message-cross-post-followup-to)
+       (message-cross-post-followup-to, message-mode-map)
+       (message-generate-unsubscribed-mail-followup-to)
+       (message-make-mail-followup-to): Minor changes to doc-strings and
+       error messages.  Updated copyright line.
+
+       * message.el (message-make-mail-followup-to,
+       message-generate-unsubscribed-mail-followup-to): New function
+       names.  Renamed functions: "-mft" -> "-mail-followup-to".
+       (message-make-mft, message-gen-unsubscribed-mft): Removed function
+       names.
+
+       * mml.el (mml-preview-insert-mail-followup-to): New function name.
+       (mml-preview-insert-mft): Removed function name.
+       (mml-preview): Use new function names.
+
+       * gnus-art.el (gnus-article-edit-mode-map): Use new function names.
+
+       * message.el (message-mode-field-menu): Moved header related
+       commands from "Message" to "Field" menu.
+
+2003-01-07  Reiner Steib  <Reiner.Steib@gmx.de>
+
+       * message.el (message-generate-headers-first): Added customization
+       if variable is a list.
+
+2003-01-07  Michael Shields  <shields@msrl.com>
+
+       * gnus-art.el (gnus-article-next-page): Correctly handle the case
+       where the last line of the article is the last line of the window.
+
+2003-01-08  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-msg.el (gnus-debug): Use ignore-errors.
+
+       * gnus-agent.el (gnus-agent-fetch-selected-article): Use
+       `gnus-summary-update-line'.
+
+2003-01-08  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-art.el (gnus-unbuttonized-mime-types)
+       (gnus-buttonized-mime-types): Doc fix.
+
+2003-01-08  Jesper Harder  <harder@ifa.au.dk>
+
+       * mm-decode.el (mm-inline-media-tests): .xpm is 'x-xpixmap'.
+
+2003-01-07  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * nnrss.el (nnrss-group-alist): Add and clear up.
+
+2003-01-07  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * spam.el: removed unnecessary condition-case for loading bbdb-com.el
+
+       * lpath.el (bbdb-search): added BBDB functions for a better way to
+       fix missing functions
+
+       * spam.el (spam-check-ifile): if should be an unless
+
+       * spam.el: define 'ignore alias for spam-BBDB-register-routine,
+       spam-enter-ham-BBDB, and bbdb-create-internal initially to hush up warnings
+       (spam-ifile-all-categories): doc string fixed to be less than 80 chars
+
+2003-01-07  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-sum.el (gnus-summary-make-menu-bar): Added
+       gnus-summary-refer-thread to thread menu.
+
+2002-01-07  Kevin Greiner  <kgreiner@xpediantsolutions.com>
+
+       * gnus-agent.el (gnus-agent-fetch-group-1): When fetching within a
+       summary buffer, articles that cannot be fetched are marked as
+       canceled.
+
+       * nntp.el (nntp-with-open-group): The quit signal handler must
+       propagate the quit signal to the next outer handler so that the
+       caller knows that the request aborted abnormally.
+
+2003-01-07  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * spam.el (spam-check-ifile, spam-ifile-register-with-ifile)
+       (spam-ifile-register-spam-routine)
+       (spam-ifile-register-ham-routine): added ifile functionality that
+       does not use ifile-gnus.el to classify and register articles
+       (spam-get-article-as-string): convenience function
+       (spam-summary-prepare-exit): added ifile spam and ham registration
+       (spam-ifile-all-categories, spam-ifile-spam-category)
+       (spam-ifile-path, spam-ifile): added customization options
+
+       * gnus.el (gnus-group-ham-exit-processor-ifile): added ifile ham
+       exit processor
+       (spam-process): added gnus-group-ham-exit-processor-ifile to the
+       list of choices
+
+2003-01-07  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-score.el (gnus-score-followup): Also score immediate
+       followups.
+
+2003-01-06  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * nnweb.el (nnweb-asynchronous-p): Changed to nil.
+
+2003-01-07  Simon Josefsson  <jas@extundo.com>
+
+       * message.el (message-mode-menu): Fix receipt balloon help.
+
+2003-01-07  Jesper Harder  <harder@ifa.au.dk>
+
+       * gnus-msg.el (gnus-group-post-news): Don't assume that "" will
+       always be interpreted as news.
+
+2003-01-07  Simon Josefsson  <jas@extundo.com>
+
+       * gnus-sieve.el (gnus-sieve-script): Use the crosspost argument to
+       gnus-sieve-script, instead of the global variable
+       gnus-sieve-crosspost.  One-line patch from Steinar Bang
+       <sb@dod.no>.
+
+2002-01-06  Kevin Greiner  <kgreiner@xpediantsolutions.com>
+
+       * gnus.el: Renamed gnus-summary-*-uncached-face as
+       gnus-summary-*-undownloaded-face to avoid confusing the agent with
+       the cache.
+
+       * gnus-sum.el: Ditto.
+
+2002-01-06  Kevin Greiner  <kgreiner@xpediantsolutions.com>
+
+       * gnus-agent.el (gnus-agent-fetch-group): Modified to permit execution
+       in either the group or summary buffer.
+       New command "JS", in summary buffer, will fetch articles per the
+       group's category, predicate, and processable flags.
+       (gnus-agent-summary-fetch-series): Rewritten to call
+       gnus-agent-session-fetch-group once with all articles in the
+       series.
+       (gnus-agent-summary-fetch-group): Fixed bug and modified code to
+       return list of fetched articles.
+       (gnus-agent-fetch-articles): Split fetch list into sublists such
+       that the article buffer is only slightly larger than
+       gnus-agent-max-fetch-size.  Added unwind-protect to ensure that
+       the group's article alist is saved.
+       (gnus-agent-fetch-headers): The 'killed' and 'cached' marks no
+       longer result in the agent trying to fetch an article.
+       (gnus-agent-fetch-group-1): Can now be called in either the group
+       or summary buffer.  Removed the max-fetch-size code that I added
+       on 2002-12-13 as that capability is now part of
+       gnus-agent-fetch-articles.  Added code to update summary buffer.
+       When called in the group buffer, articles that can not be fetched
+       are AUTOMATICALLY MARKED AS READ.
+
+       * gnus-sum.el (): Modified eval-when-compile to minimize
+       misleading compilation warnings.
+       (gnus-update-summary-mark-positions): Changed code to use
+       gnus-undownloaded-mark rather than gnus-downloaded-mark.
+
+       * nnheader.el (nnheader-insert-nov-file): Do not try to insert an
+       empty file as the parser assumes that the file isn't empty.
+
+       * nntp.el (nntp-send-string): The process-send-string call can,
+       because it performs I/O on the process, change the process' state
+       from open to closed.  If this happens, call nntp-report
+       immediately to report the broken connection.
+       (nntp-report): Rewritten to avoid needing a global variable to
+       determine the appropriate course of action.  Instead, two function
+       implementations are provided and the nntp-report function value is
+       bound to the appropriate implementation.
+       (nntp-retrieve-data): Moved nntp-report call to end of implementation.
+       (nntp-with-open-group): Now binds nntp-report's function cell
+       rather than binding gnus-with-open-group-first-pass.  Added a
+       condition-case to detect a quit during a nntp command.  When the
+       quit occurs, the current connection is closed as a fetch articles
+       request could have several megabytes queued up for reading.
+       (nntp-retrieve-headers): Bind articles to itself.  If
+       nntp-with-open-group repeats this command, I must have access to
+       the original list of articles.
+       (nntp-retrieve-groups): Ditto for groups.
+       (nntp-retrieve-articles): Ditto for articles.
+       (*): Replaced nntp-possibly-change-group calls to
+       nntp-with-open-group forms in all, but one, occurrance.
+       (nntp-accept-process-output): Bug fix. Detect when called with
+       null process.
+
+2003-01-06  Jesper Harder  <harder@ifa.au.dk>
+
+       * mm-util.el (mm-find-mime-charset-region): Don't do Latin-9 hack
+       if we don't need to.
+       (mm-iso-8859-x-to-15-region): Fix misplaced parenthesis.
+
+2003-01-06  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-group.el (gnus-group-make-web-group): Pass the select
+       method on to group-create.
+       (gnus-group-line-format-alist): %U is an integer.
+
+       * gnus-sum.el (gnus-summary-exit-no-update): Don't update
+       ephemeral groups.
+       (gnus-summary-read-group-1): Ditto.
+       (gnus-group-make-articles-read): Ditto.
+
+       * mm-url.el (mm-url-program): Doc fix.
+
+       * message.el (message-mode-map): Rebound
+       message-insert-wide-reply.
+
+2003-01-05  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * gnus-xmas.el (gnus-xmas-group-startup-message): Bind the oort
+       color as `gnus-group-startup-message' does.
+
+2003-01-05  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * spam.el: fixed line lengths to 80 chars or less
+
+       * gnus-sum.el (gnus-read-mark-p): added the spam-mark as a
+       "not-read" mark
+       (gnus-summary-mark-forward): added the spam-mark to the list of
+       marks not to be marked as "read" when viewed
+
+2003-01-05  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-msg.el (gnus-inews-make-draft): Quote article-reply.
+
+       * gnus-group.el (gnus-number-of-unseen-articles-in-group):
+       Protect against unactive groups.
+
+       * message.el (message-check-news-header-syntax): Check long
+       header lines.
+       (message-check-news-header-syntax): Update `start'.
+
+       * gnus-group.el (gnus-group-expire-articles): Doc fix.
+       (gnus-group-line-format): %U.
+       (gnus-group-line-format-alist): ?U.
+       (gnus-number-of-unseen-articles-in-group): New function.
+
+       * nntp.el (nntp-accept-process-output): Use a 0.1 second timeout.
+
+       * gnus.el (gnus-version-number): Bump version number.
+
 2003-01-05 01:53:30 Lars Magne Ingebrigtsen <lars@ingebrigtsen.no>
 
        * gnus.el: Oort Gnus v0.10 is released.
 2003-01-05 01:53:30 Lars Magne Ingebrigtsen <lars@ingebrigtsen.no>
 
        * gnus.el: Oort Gnus v0.10 is released.
 
 2003-01-04  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
 
 2003-01-04  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
-       * gnus.el (gnus-variable-list): Write gnus-format-specs last. 
+       * gnus.el (gnus-variable-list): Write gnus-format-specs last.
 
        * gnus-sum.el (gnus-summary-goto-subjects): Fix typo.
 
 2003-01-04  Kevin Ryde  <user42@zip.com.au>
 
        * gnus-art.el (gnus-mime-jka-compr-maybe-uncompress): New
 
        * gnus-sum.el (gnus-summary-goto-subjects): Fix typo.
 
 2003-01-04  Kevin Ryde  <user42@zip.com.au>
 
        * gnus-art.el (gnus-mime-jka-compr-maybe-uncompress): New
-       function. 
+       function.
 
 2003-01-04  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
 
 2003-01-04  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
-       * gnus-sum.el (gnus-summary-exit): Bind gnus-group-is-exiting-p. 
+       * gnus-sum.el (gnus-summary-exit): Bind gnus-group-is-exiting-p.
        (gnus-summary-read-group-1): Update group line.
        (gnus-summary-exit-no-update): Update group on exit.
 
        (gnus-summary-read-group-1): Update group line.
        (gnus-summary-exit-no-update): Update group on exit.
 
 2003-01-02  Teodor Zlatanov  <tzz@lifelogs.com>
 
        * spam.el (spam-group-spam-contents-p, spam-group-ham-contents-p)
 2003-01-02  Teodor Zlatanov  <tzz@lifelogs.com>
 
        * spam.el (spam-group-spam-contents-p, spam-group-ham-contents-p)
-       (spam-group-processor-p, spam-group-processor-bogofilter-p) 
-       (spam-group-processor-ifile-p, spam-group-processor-blacklist-p) 
-       (spam-group-processor-whitelist-p, spam-group-processor-BBDB-p) 
-       (spam-mark-spam-as-expired-and-move-routine) 
-       (spam-generic-register-routine, spam-BBDB-register-routine) 
-       (spam-ifile-register-routine, spam-blacklist-register-routine) 
+       (spam-group-processor-p, spam-group-processor-bogofilter-p)
+       (spam-group-processor-ifile-p, spam-group-processor-blacklist-p)
+       (spam-group-processor-whitelist-p, spam-group-processor-BBDB-p)
+       (spam-mark-spam-as-expired-and-move-routine)
+       (spam-generic-register-routine, spam-BBDB-register-routine)
+       (spam-ifile-register-routine, spam-blacklist-register-routine)
        (spam-whitelist-register-routine): new functions
        (spam-summary-prepare-exit): added summary exit processing (expire
        or move) of spam-marked articles for spam groups; added slots for
        (spam-whitelist-register-routine): new functions
        (spam-summary-prepare-exit): added summary exit processing (expire
        or move) of spam-marked articles for spam groups; added slots for
        (pop3-read-response): Ditto.
 
        * gnus-msg.el (gnus-setup-message): Get the evaliation order
        (pop3-read-response): Ditto.
 
        * gnus-msg.el (gnus-setup-message): Get the evaliation order
-       right. 
+       right.
        (gnus-inews-make-draft): New function.
        (gnus-setup-message): Use it.
 
        (gnus-inews-make-draft): New function.
        (gnus-setup-message): Use it.
 
index d78c251..1f15364 100644 (file)
   :group 'gnus-outlook-deuglify)
 
 (defcustom gnus-outlook-deuglify-attrib-verb-regexp
   :group 'gnus-outlook-deuglify)
 
 (defcustom gnus-outlook-deuglify-attrib-verb-regexp
-  "wrote\\|writes\\|says\\|schrieb\\|schreibt\\|meinte\\|skrev\\|a Ã©crit\\|schreef"
+  "wrote\\|writes\\|says\\|schrieb\\|schreibt\\|meinte\\|skrev\\|a Ã©crit\\|schreef\\|escribió"
   "Regular expression matching the verb used in an attribution line."
   :type 'string
   :group 'gnus-outlook-deuglify)
   "Regular expression matching the verb used in an attribution line."
   :type 'string
   :group 'gnus-outlook-deuglify)
   :type 'string
   :group 'gnus-outlook-deuglify)
 
   :type 'string
   :group 'gnus-outlook-deuglify)
 
+;;;###autoload
+(defcustom gnus-outlook-display-hook nil
+  "A hook called after an deuglified article has been prepared.
+It is run after `gnus-article-prepare-hook'."
+  :type 'hook
+  :group 'gnus-outlook-deuglify)
 
 ;; Functions
 
 
 ;; Functions
 
+(defun gnus-outlook-display-article-buffer ()
+  "Redisplay current buffer or article buffer."
+  (with-current-buffer (or gnus-article-buffer (current-buffer))
+    ;; "Emulate" `gnus-article-prepare-display' without calling
+    ;; it. Calling `gnus-article-prepare-display' on an already
+    ;; prepared article removes all MIME parts.  I'm unsure whether
+    ;; this is a bug or not.
+    (gnus-article-highlight t)
+    (gnus-treat-article nil)
+    (gnus-run-hooks 'gnus-article-prepare-hook
+                   'gnus-outlook-display-hook)))
+
 ;;;###autoload
 ;;;###autoload
-(defun gnus-outlook-unwrap-lines ()
-  "Unwrap lines that appear to be wrapped citation lines.
+(defun gnus-outlook-unwrap-lines (&optional nodisplay)
+  "Unwrap lines that appear to be wrapped citation lines.  
 You can control what lines will be unwrapped by frobbing
 You can control what lines will be unwrapped by frobbing
-`gnus-outlook-deuglify-unwrap-min' and
-`gnus-outlook-deuglify-unwrap-max', indicating the miminum and maximum
-length of an unwrapped citation line."
-  (interactive)
+`gnus-outlook-deuglify-unwrap-min' and `gnus-outlook-deuglify-unwrap-max',
+indicating the miminum and maximum length of an unwrapped citation line.  If
+NODISPLAY is non-nil, don't redisplay the article buffer."
+  (interactive "P")
   (save-excursion
     (let ((case-fold-search nil)
          (inhibit-read-only t)
   (save-excursion
     (let ((case-fold-search nil)
          (inhibit-read-only t)
@@ -308,7 +326,8 @@ length of an unwrapped citation line."
                     (< (+ len12 len3) gnus-outlook-deuglify-unwrap-max))
                (progn
                  (replace-match "\\1\\2 \\3")
                     (< (+ len12 len3) gnus-outlook-deuglify-unwrap-max))
                (progn
                  (replace-match "\\1\\2 \\3")
-                 (goto-char (match-beginning 0))))))))))
+                 (goto-char (match-beginning 0)))))))))
+  (unless nodisplay (gnus-outlook-display-article-buffer)))
 
 (defun gnus-outlook-rearrange-article (attr-start)
   "Put the text from `attr-start' to the end of buffer at the top of the article buffer."
 
 (defun gnus-outlook-rearrange-article (attr-start)
   "Put the text from `attr-start' to the end of buffer at the top of the article buffer."
@@ -400,45 +419,46 @@ length of an unwrapped citation line."
              (match-beginning 0)))))))
 
 ;;;###autoload
              (match-beginning 0)))))))
 
 ;;;###autoload
-(defun gnus-outlook-repair-attribution ()
-  "Repair a broken attribution line."
-  (interactive)
-  (or
-   (gnus-outlook-repair-attribution-other)
-   (gnus-outlook-repair-attribution-block)
-   (gnus-outlook-repair-attribution-outlook)))
-
-(defun gnus-outlook-rearrange-citation ()
-  "Repair broken citations."
-  (let ((attrib-start (gnus-outlook-repair-attribution)))
+(defun gnus-outlook-repair-attribution (&optional nodisplay)
+  "Repair a broken attribution line.
+If NODISPLAY is non-nil, don't redisplay the article buffer."
+  (interactive "P")
+  (let ((attrib-start
+        (or
+         (gnus-outlook-repair-attribution-other)
+         (gnus-outlook-repair-attribution-block)
+         (gnus-outlook-repair-attribution-outlook))))
+    (unless nodisplay (gnus-outlook-display-article-buffer))
+    attrib-start))
+
+(defun gnus-outlook-rearrange-citation (&optional nodisplay)
+  "Repair broken citations.
+If NODISPLAY is non-nil, don't redisplay the article buffer."
+  (interactive "P")
+  (let ((attrib-start (gnus-outlook-repair-attribution 'nodisplay)))
     ;; rearrange citations if an attribution line has been recognized
     (if attrib-start
     ;; rearrange citations if an attribution line has been recognized
     (if attrib-start
-       (gnus-outlook-rearrange-article attrib-start))))
+       (gnus-outlook-rearrange-article attrib-start)))
+  (unless nodisplay (gnus-outlook-display-article-buffer)))
 
 ;;;###autoload
 
 ;;;###autoload
-(defun gnus-outlook-deuglify-article ()
-  "Deuglify broken Outlook (Express) articles."
-  (interactive)
+(defun gnus-outlook-deuglify-article (&optional nodisplay)
+  "Deuglify broken Outlook (Express) articles.
+If NODISPLAY is non-nil, don't redisplay the article buffer."
+  (interactive "P")
   ;; apply treatment of dumb quotes
   (gnus-article-treat-dumbquotes)
   ;; repair wrapped cited lines
   ;; apply treatment of dumb quotes
   (gnus-article-treat-dumbquotes)
   ;; repair wrapped cited lines
-  (gnus-outlook-unwrap-lines)
+  (gnus-outlook-unwrap-lines 'nodisplay)
   ;; repair attribution line
   ;; repair attribution line
-  (gnus-outlook-rearrange-citation))
+  (gnus-outlook-rearrange-citation 'nodisplay)
+  (unless nodisplay (gnus-outlook-display-article-buffer)))
 
 ;;;###autoload
 (defun gnus-article-outlook-deuglify-article ()
   "Deuglify broken Outlook (Express) articles and redisplay."
   (interactive)
 
 ;;;###autoload
 (defun gnus-article-outlook-deuglify-article ()
   "Deuglify broken Outlook (Express) articles and redisplay."
   (interactive)
-  (gnus-outlook-deuglify-article)
-  (with-current-buffer (or gnus-article-buffer (current-buffer))
-    ;; "Emulate" `gnus-article-prepare-display' without calling
-    ;; it. Calling `gnus-article-prepare-display' on an already
-    ;; prepared article removes all MIME parts.  I'm unsure whether
-    ;; this is a bug or not.
-    (gnus-article-highlight t)
-    (gnus-treat-article nil)
-    (gnus-run-hooks 'gnus-article-prepare-hook)))
+  (gnus-outlook-deuglify-article nil))
 
 (provide 'deuglify)
 
 
 (provide 'deuglify)
 
index 308cf39..ed45a64 100644 (file)
@@ -345,6 +345,7 @@ node `(gnus)Server Buffer'.")
 (gnus-define-keys gnus-agent-summary-mode-map
   "Jj" gnus-agent-toggle-plugged
   "Ju" gnus-agent-summary-fetch-group
 (gnus-define-keys gnus-agent-summary-mode-map
   "Jj" gnus-agent-toggle-plugged
   "Ju" gnus-agent-summary-fetch-group
+  "JS" gnus-agent-fetch-group
   "Js" gnus-agent-summary-fetch-series
   "J#" gnus-agent-mark-article
   "J\M-#" gnus-agent-unmark-article
   "Js" gnus-agent-summary-fetch-series
   "J#" gnus-agent-mark-article
   "J\M-#" gnus-agent-unmark-article
@@ -545,12 +546,13 @@ be a select method."
     (error "Groups can't be fetched when Gnus is unplugged"))
   (gnus-group-iterate n 'gnus-agent-fetch-group))
 
     (error "Groups can't be fetched when Gnus is unplugged"))
   (gnus-group-iterate n 'gnus-agent-fetch-group))
 
-(defun gnus-agent-fetch-group (group)
+(defun gnus-agent-fetch-group (&optional group)
   "Put all new articles in GROUP into the Agent."
   (interactive (list (gnus-group-group-name)))
   (let ((state gnus-plugged))
     (unwind-protect
        (progn
   "Put all new articles in GROUP into the Agent."
   (interactive (list (gnus-group-group-name)))
   (let ((state gnus-plugged))
     (unwind-protect
        (progn
+          (setq group (or group gnus-newsgroup-name))
          (unless group
            (error "No group on the current line"))
          (unless state
          (unless group
            (error "No group on the current line"))
          (unless state
@@ -783,27 +785,37 @@ article's mark is toggled."
        (setq gnus-newsgroup-undownloaded (cdr undownloaded))))))
 
 (defun gnus-agent-catchup ()
        (setq gnus-newsgroup-undownloaded (cdr undownloaded))))))
 
 (defun gnus-agent-catchup ()
-  "Mark all undownloaded articles as read."
+  "Mark all articles as read that are neither cached, downloaded, nor downloadable."
   (interactive)
   (save-excursion
   (interactive)
   (save-excursion
-    (while gnus-newsgroup-undownloaded
-      (gnus-summary-mark-article
-       (pop gnus-newsgroup-undownloaded) gnus-catchup-mark)))
-  (gnus-summary-position-point))
+    (let ((articles gnus-newsgroup-undownloaded))
+      (when (or gnus-newsgroup-downloadable
+                gnus-newsgroup-cached)
+        (setq articles (gnus-sorted-ndifference (gnus-sorted-ndifference (copy-sequence articles) gnus-newsgroup-downloadable) gnus-newsgroup-cached)))
+
+      (while articles
+        (gnus-summary-mark-article
+         (pop articles) gnus-catchup-mark)))
+    (gnus-summary-position-point)))
 
 (defun gnus-agent-summary-fetch-series ()
   (interactive)
 
 (defun gnus-agent-summary-fetch-series ()
   (interactive)
-  (let ((dl gnus-newsgroup-downloadable))
-    (while gnus-newsgroup-processable
-      (let* ((art (car (last gnus-newsgroup-processable)))
-             (gnus-newsgroup-downloadable (list art)))
-        (gnus-summary-goto-subject art)
-        (sit-for 0)
-        (gnus-agent-summary-fetch-group)
-        (setq dl (delq art dl))
-        (gnus-summary-remove-process-mark art)
-        (sit-for 0)))
-    (setq gnus-newsgroup-downloadable dl)))
+  (when gnus-newsgroup-processable
+    (setq gnus-newsgroup-downloadable
+          (let* ((dl gnus-newsgroup-downloadable)
+                 (gnus-newsgroup-downloadable (sort (copy-sequence gnus-newsgroup-processable) '<))
+                 (fetched-articles (gnus-agent-summary-fetch-group)))
+            ;; The preceeding call to (gnus-agent-summary-fetch-group)
+            ;; updated gnus-newsgroup-downloadable to remove each
+            ;; article successfully fetched.
+
+            ;; For each article that I processed, remove its
+            ;; processable mark IF the article is no longer
+            ;; downloadable (i.e. it's already downloaded)
+            (dolist (article gnus-newsgroup-processable)
+              (unless (memq article gnus-newsgroup-downloadable)
+                (gnus-summary-remove-process-mark article)))
+            (gnus-sorted-ndifference dl fetched-articles)))))
 
 (defun gnus-agent-summary-fetch-group (&optional all)
   "Fetch the downloadable articles in the group.
 
 (defun gnus-agent-summary-fetch-group (&optional all)
   "Fetch the downloadable articles in the group.
@@ -813,7 +825,8 @@ Optional arg ALL, if non-nil, means to fetch all articles."
         (if all gnus-newsgroup-articles
           gnus-newsgroup-downloadable))
        (gnus-command-method (gnus-find-method-for-group gnus-newsgroup-name))
         (if all gnus-newsgroup-articles
           gnus-newsgroup-downloadable))
        (gnus-command-method (gnus-find-method-for-group gnus-newsgroup-name))
-       (state gnus-plugged))
+       (state gnus-plugged)
+        fetched-articles)
     (unwind-protect
        (progn
          (unless state
     (unwind-protect
        (progn
          (unless state
@@ -821,19 +834,22 @@ Optional arg ALL, if non-nil, means to fetch all articles."
          (unless articles
            (error "No articles to download"))
          (gnus-agent-with-fetch
          (unless articles
            (error "No articles to download"))
          (gnus-agent-with-fetch
-             (setq gnus-newsgroup-undownloaded
-                   (gnus-sorted-ndifference gnus-newsgroup-undownloaded
-                                            (gnus-agent-fetch-articles gnus-newsgroup-name articles))))
+            (setq gnus-newsgroup-undownloaded
+                  (gnus-sorted-ndifference gnus-newsgroup-undownloaded
+                                           (setq fetched-articles (gnus-agent-fetch-articles gnus-newsgroup-name articles)))))
          (save-excursion
          (save-excursion
-           (dolist (article articles)
+
+            (dolist (article articles)
              (setq gnus-newsgroup-downloadable
                    (delq article gnus-newsgroup-downloadable))
              (setq gnus-newsgroup-downloadable
                    (delq article gnus-newsgroup-downloadable))
-             (if gnus-agent-mark-unread-after-downloaded
-                 (gnus-summary-mark-article article gnus-unread-mark))
-             (gnus-summary-update-download-mark article))))
+              (if gnus-agent-mark-unread-after-downloaded
+                  (gnus-summary-mark-article article gnus-unread-mark))
+              (when (gnus-summary-goto-subject article nil t)
+                (gnus-summary-update-download-mark article)))))
       (when (and (not state)
                 gnus-plugged)
       (when (and (not state)
                 gnus-plugged)
-       (gnus-agent-toggle-plugged nil)))))
+       (gnus-agent-toggle-plugged nil)))
+    fetched-articles))
 
 (defun gnus-agent-fetch-selected-article ()
   "Fetch the current article as it is selected.
 
 (defun gnus-agent-fetch-selected-article ()
   "Fetch the current article as it is selected.
@@ -844,8 +860,11 @@ This can be added to `gnus-select-article-hook' or
       (when (gnus-agent-fetch-articles
              gnus-newsgroup-name
             (list gnus-current-article))
       (when (gnus-agent-fetch-articles
              gnus-newsgroup-name
             (list gnus-current-article))
-       (setq gnus-newsgroup-undownloaded (delq gnus-current-article gnus-newsgroup-undownloaded))
-       (gnus-summary-update-article gnus-current-article)))))
+       (setq gnus-newsgroup-undownloaded
+             (delq gnus-current-article gnus-newsgroup-undownloaded))
+       (gnus-summary-update-article-line
+        gnus-current-article
+        (gnus-summary-article-header gnus-current-article))))))
 
 ;;;
 ;;; Internal functions
 
 ;;;
 ;;; Internal functions
@@ -975,82 +994,118 @@ This can be added to `gnus-select-article-hook' or
 
 (defun gnus-agent-fetch-articles (group articles)
   "Fetch ARTICLES from GROUP and put them into the Agent."
 
 (defun gnus-agent-fetch-articles (group articles)
   "Fetch ARTICLES from GROUP and put them into the Agent."
-  (gnus-agent-load-alist group)
   (when articles
   (when articles
-    ;; Prune off articles that we have already fetched.
-    (while (and articles
-               (cdr (assq (car articles) gnus-agent-article-alist)))
-      (pop articles))
-    (let ((arts articles))
-      (while (cdr arts)
-       (if (cdr (assq (cadr arts) gnus-agent-article-alist))
-           (setcdr arts (cddr arts))
-         (setq arts (cdr arts)))))
-    (when articles
-      (let* ((fetched-articles (list nil))
-            (tail-fetched-articles fetched-articles)
-            (dir (concat
-                 (gnus-agent-directory)
-                 (gnus-agent-group-path group) "/"))
-           (date (time-to-days (current-time)))
-           (case-fold-search t)
-            pos crosses id)
-       (gnus-make-directory dir)
-       (gnus-message 7 "Fetching articles for %s..." group)
-       ;; Fetch the articles from the backend.
-       (if (gnus-check-backend-function 'retrieve-articles group)
-           (setq pos (gnus-retrieve-articles articles group))
-         (with-temp-buffer
-           (let (article)
-             (while (setq article (pop articles))
-               (gnus-message 10 "Fetching article %s for %s..."
-                             article group)
-               (when (or
-                      (gnus-backlog-request-article group article
-                                                    nntp-server-buffer)
-                      (gnus-request-article article group))
-                 (goto-char (point-max))
-                 (push (cons article (point)) pos)
-                 (insert-buffer-substring nntp-server-buffer)))
-             (copy-to-buffer nntp-server-buffer (point-min) (point-max))
-             (setq pos (nreverse pos)))))
-       ;; Then save these articles into the Agent.
-       (save-excursion
-         (set-buffer nntp-server-buffer)
-         (while pos
-           (narrow-to-region (cdar pos) (or (cdadr pos) (point-max)))
-           (goto-char (point-min))
-           (unless (eobp)  ;; Don't save empty articles.
-             (when (search-forward "\n\n" nil t)
-               (when (search-backward "\nXrefs: " nil t)
-                 ;; Handle cross posting.
-                  (goto-char (match-end 0)) ; move to end of header name
-                 (skip-chars-forward "^ ") ; skip server name
-                 (skip-chars-forward " ")
-                 (setq crosses nil)
-                 (while (looking-at "\\([^: \n]+\\):\\([0-9]+\\) *")
-                   (push (cons (buffer-substring (match-beginning 1)
-                                                 (match-end 1))
-                               (string-to-int (buffer-substring (match-beginning 2)
-                                                                 (match-end 2))))
-                         crosses)
-                   (goto-char (match-end 0)))
-                 (gnus-agent-crosspost crosses (caar pos) date)))
-             (goto-char (point-min))
-             (if (not (re-search-forward
-                       "^Message-ID: *<\\([^>\n]+\\)>" nil t))
-                 (setq id "No-Message-ID-in-article")
-               (setq id (buffer-substring (match-beginning 1) (match-end 1))))
-             (write-region-as-coding-system
-              gnus-agent-file-coding-system (point-min) (point-max)
-              (concat dir (number-to-string (caar pos))) nil 'silent)
-
-             (gnus-agent-append-to-list tail-fetched-articles (caar pos)))
-           (widen)
-           (pop pos)))
-
-       (gnus-agent-save-alist group (cdr fetched-articles) date)
-       (cdr fetched-articles)))))
+    (gnus-agent-load-alist group)
+    (let* ((alist   gnus-agent-article-alist)
+           (headers (if (< (length articles) 2) nil gnus-newsgroup-headers))
+           (selected-sets (list nil))
+           (current-set-size 0)
+           article
+           header-number)
+      ;; Check each article
+      (while (setq article (pop articles))
+        ;; Skip alist entries preceeding this article
+        (while (> article (or (caar alist) (1+ article)))
+          (setq alist (cdr alist)))
+
+        ;; Prune off articles that we have already fetched.
+        (unless (and (eq article (caar alist))
+                     (cdar alist))
+          ;; Skip headers preceeding this article
+          (while (> article 
+                    (setq header-number
+                          (let* ((header (car headers)))
+                            (if header
+                                (mail-header-number header)
+                              (1+ article)))))
+            (setq headers (cdr headers)))
+
+          ;; Add this article to the current set
+          (setcar selected-sets (cons article (car selected-sets)))
+
+          ;; Update the set size, when the set is too large start a
+          ;; new one.  I do this after adding the article as I want at
+          ;; least one article in each set.
+          (when (< gnus-agent-max-fetch-size
+                   (setq current-set-size (+ current-set-size (if (= header-number article)
+                                                                  (mail-header-chars (car headers))
+                                                                0))))
+            (setcar selected-sets (nreverse (car selected-sets)))
+            (setq selected-sets (cons nil selected-sets)
+                  current-set-size 0))))
+
+      (when (or (cdr selected-sets) (car selected-sets))
+        (let* ((fetched-articles (list nil))
+               (tail-fetched-articles fetched-articles)
+               (dir (concat
+                     (gnus-agent-directory)
+                     (gnus-agent-group-path group) "/"))
+               (date (time-to-days (current-time)))
+               (case-fold-search t)
+               pos crosses id)
+
+          (setcar selected-sets (nreverse (car selected-sets)))
+          (setq selected-sets (nreverse selected-sets))
+
+          (gnus-make-directory dir)
+          (gnus-message 7 "Fetching articles for %s..." group)
+          
+          (unwind-protect
+              (while (setq articles (pop selected-sets))
+                ;; Fetch the articles from the backend.
+                (if (gnus-check-backend-function 'retrieve-articles group)
+                    (setq pos (gnus-retrieve-articles articles group))
+                  (with-temp-buffer
+                    (let (article)
+                      (while (setq article (pop articles))
+                        (gnus-message 10 "Fetching article %s for %s..."
+                                      article group)
+                        (when (or
+                               (gnus-backlog-request-article group article
+                                                             nntp-server-buffer)
+                               (gnus-request-article article group))
+                          (goto-char (point-max))
+                          (push (cons article (point)) pos)
+                          (insert-buffer-substring nntp-server-buffer)))
+                      (copy-to-buffer nntp-server-buffer (point-min) (point-max))
+                      (setq pos (nreverse pos)))))
+                ;; Then save these articles into the Agent.
+                (save-excursion
+                  (set-buffer nntp-server-buffer)
+                  (while pos
+                    (narrow-to-region (cdar pos) (or (cdadr pos) (point-max)))
+                    (goto-char (point-min))
+                    (unless (eobp) ;; Don't save empty articles.
+                      (when (search-forward "\n\n" nil t)
+                        (when (search-backward "\nXrefs: " nil t)
+                          ;; Handle cross posting.
+                          (goto-char (match-end 0)) ; move to end of header name
+                          (skip-chars-forward "^ ") ; skip server name
+                          (skip-chars-forward " ")
+                          (setq crosses nil)
+                          (while (looking-at "\\([^: \n]+\\):\\([0-9]+\\) *")
+                            (push (cons (buffer-substring (match-beginning 1)
+                                                          (match-end 1))
+                                        (string-to-int (buffer-substring (match-beginning 2)
+                                                                         (match-end 2))))
+                                  crosses)
+                            (goto-char (match-end 0)))
+                          (gnus-agent-crosspost crosses (caar pos) date)))
+                      (goto-char (point-min))
+                      (if (not (re-search-forward
+                                "^Message-ID: *<\\([^>\n]+\\)>" nil t))
+                          (setq id "No-Message-ID-in-article")
+                        (setq id (buffer-substring (match-beginning 1) (match-end 1))))
+                     (write-region-as-coding-system
+                      gnus-agent-file-coding-system (point-min) (point-max)
+                      (concat dir (number-to-string (caar pos))) nil 'silent)
+
+                      (gnus-agent-append-to-list tail-fetched-articles (caar pos)))
+                    (widen)
+                    (pop pos))))
+
+            (gnus-agent-save-alist group (cdr fetched-articles) date))
+          (cdr fetched-articles))))))
 
 (defun gnus-agent-crosspost (crosses article &optional date)
   (setq date (or date t))
 
 (defun gnus-agent-crosspost (crosses article &optional date)
   (setq date (or date t))
@@ -1082,11 +1137,24 @@ This can be added to `gnus-select-article-hook' or
         (gnus-agent-check-overview-buffer))
       (pop crosses))))
 
         (gnus-agent-check-overview-buffer))
       (pop crosses))))
 
+(defun gnus-agent-backup-overview-buffer ()
+  (when gnus-newsgroup-name
+    (let ((root (gnus-agent-article-name ".overview" gnus-newsgroup-name))
+          (cnt 0)
+          name)
+      (while (file-exists-p (setq name (concat root "~" (int-to-string (setq cnt (1+ cnt))) "~"))))
+      (write-region (point-min) (point-max) name nil 'no-msg)
+      (gnus-message 1 "Created backup copy of overview in %s." name)
+      )
+    )
+  t)
+
 (defun gnus-agent-check-overview-buffer (&optional buffer)
   "Check the overview file given for sanity.
 In particular, checks that the file is sorted by article number
 and that there are no duplicates."
 (defun gnus-agent-check-overview-buffer (&optional buffer)
   "Check the overview file given for sanity.
 In particular, checks that the file is sorted by article number
 and that there are no duplicates."
-  (let ((prev-num -1))
+  (let ((prev-num -1)
+        (backed-up nil))
     (save-excursion
       (when buffer
        (set-buffer buffer))
     (save-excursion
       (when buffer
        (set-buffer buffer))
@@ -1102,22 +1170,30 @@ and that there are no duplicates."
            (cond
             ((or (not (integerp cur))
                  (not (eq (char-after) ?\t)))
            (cond
             ((or (not (integerp cur))
                  (not (eq (char-after) ?\t)))
+              (or backed-up
+                  (setq backed-up (gnus-agent-backup-overview-buffer)))
              (gnus-message 1
                            "Overview buffer contains garbage '%s'."
                            (buffer-substring
                             p (gnus-point-at-eol))))
             ((= cur prev-num)
              (gnus-message 1
                            "Overview buffer contains garbage '%s'."
                            (buffer-substring
                             p (gnus-point-at-eol))))
             ((= cur prev-num)
-             (gnus-message 1
+             (or backed-up
+                  (setq backed-up (gnus-agent-backup-overview-buffer)))
+              (gnus-message 1
                            "Duplicate overview line for %d" cur)
              (delete-region (point) (progn (forward-line 1) (point))))
             ((< cur 0)
                            "Duplicate overview line for %d" cur)
              (delete-region (point) (progn (forward-line 1) (point))))
             ((< cur 0)
-             (gnus-message 1 "Junk article number %d" cur)
+             (or backed-up
+                  (setq backed-up (gnus-agent-backup-overview-buffer)))
+              (gnus-message 1 "Junk article number %d" cur)
              (delete-region (point) (progn (forward-line 1) (point))))
             ((< cur prev-num)
              (sort-numeric-fields 1 (point-min) (point-max))
              (goto-char (point-min))
              (setq prev-num -1)
              (delete-region (point) (progn (forward-line 1) (point))))
             ((< cur prev-num)
              (sort-numeric-fields 1 (point-min) (point-max))
              (goto-char (point-min))
              (setq prev-num -1)
-             (gnus-message 1 "Overview buffer not sorted!"))
+             (or backed-up
+                  (setq backed-up (gnus-agent-backup-overview-buffer)))
+              (gnus-message 1 "Overview buffer not sorted!"))
             (t
              (setq prev-num cur)))
            (forward-line 1)))))))
             (t
              (setq prev-num cur)))
            (forward-line 1)))))))
@@ -1172,7 +1248,7 @@ article numbers will be returned."
       ;; interesting marks.  (We have to fetch articles with boring marks
       ;; because otherwise the agent will remove their marks.)
       (dolist (arts (gnus-info-marks (gnus-get-info group)))
       ;; interesting marks.  (We have to fetch articles with boring marks
       ;; because otherwise the agent will remove their marks.)
       (dolist (arts (gnus-info-marks (gnus-get-info group)))
-        (unless (memq (car arts) '(seen recent))
+        (unless (memq (car arts) '(seen recent killed cache))
           (setq articles (gnus-range-add articles (cdr arts)))))
       (setq articles (sort (gnus-uncompress-sequence articles) '<)))
 
           (setq articles (gnus-range-add articles (cdr arts)))))
       (setq articles (sort (gnus-uncompress-sequence articles) '<)))
 
@@ -1202,6 +1278,9 @@ article numbers will be returned."
             ;; that no headers need to be fetched. -- Kevin
             (setq articles (gnus-list-range-intersection
                             articles (list (cons low high)))))))
             ;; that no headers need to be fetched. -- Kevin
             (setq articles (gnus-list-range-intersection
                             articles (list (cons low high)))))))
+
+      (gnus-message 10 "gnus-agent-fetch-headers: undownloaded articles are '%s'" (gnus-compress-sequence articles t))
+
       (save-excursion
         (set-buffer nntp-server-buffer)
 
       (save-excursion
         (set-buffer nntp-server-buffer)
 
@@ -1471,31 +1550,42 @@ of FILE placing the combined headers in nntp-server-buffer."
   "Fetch GROUP."
   (let ((gnus-command-method method)
        (gnus-newsgroup-name group)
   "Fetch GROUP."
   (let ((gnus-command-method method)
        (gnus-newsgroup-name group)
-       gnus-newsgroup-dependencies gnus-newsgroup-headers
-       gnus-newsgroup-scored gnus-headers gnus-score
-       gnus-use-cache articles arts
-       category predicate info marks score-param
+       (gnus-newsgroup-dependencies gnus-newsgroup-dependencies)
+        (gnus-newsgroup-headers gnus-newsgroup-headers)
+       (gnus-newsgroup-scored gnus-newsgroup-scored)
+       (gnus-use-cache gnus-use-cache)
        (gnus-summary-expunge-below gnus-summary-expunge-below)
        (gnus-summary-mark-below gnus-summary-mark-below)
        (gnus-orphan-score gnus-orphan-score)
        ;; Maybe some other gnus-summary local variables should also
        ;; be put here.
        (gnus-summary-expunge-below gnus-summary-expunge-below)
        (gnus-summary-mark-below gnus-summary-mark-below)
        (gnus-orphan-score gnus-orphan-score)
        ;; Maybe some other gnus-summary local variables should also
        ;; be put here.
+
+        gnus-headers
+        gnus-score
+        articles arts
+       category predicate info marks score-param
        )
     (unless (gnus-check-group group)
       (error "Can't open server for %s" group))
 
     ;; Fetch headers.
        )
     (unless (gnus-check-group group)
       (error "Can't open server for %s" group))
 
     ;; Fetch headers.
-    (when (or (gnus-active group)
+    (when (or gnus-newsgroup-active
+              (gnus-active group)
               (gnus-activate-group group))
               (gnus-activate-group group))
-      (let ((marked-articles nil))
+      (let ((marked-articles gnus-newsgroup-downloadable))
         ;; Identify the articles marked for download
         ;; Identify the articles marked for download
-        (dolist (mark gnus-agent-download-marks)
-          (let ((arts (cdr (assq mark (gnus-info-marks
-                                       (setq info (gnus-get-info group)))))))
-            (when arts
-              (setq marked-articles (nconc (gnus-uncompress-range arts)
-                                           marked-articles))
-              )))
+        (unless gnus-newsgroup-active ;; This needs to be a
+          ;; gnus-summary local variable
+          ;; that is NOT bound to any
+          ;; value above (It's global
+          ;; value should default to nil).
+          (dolist (mark gnus-agent-download-marks)
+            (let ((arts (cdr (assq mark (gnus-info-marks
+                                         (setq info (gnus-get-info group)))))))
+              (when arts
+                (setq marked-articles (nconc (gnus-uncompress-range arts)
+                                             marked-articles))
+                ))))
         (setq marked-articles (sort marked-articles '<))
 
         ;; Fetch any new articles from the server
         (setq marked-articles (sort marked-articles '<))
 
         ;; Fetch any new articles from the server
@@ -1507,11 +1597,13 @@ of FILE placing the combined headers in nntp-server-buffer."
         (when articles
           ;; Parse them and see which articles we want to fetch.
           (setq gnus-newsgroup-dependencies
         (when articles
           ;; Parse them and see which articles we want to fetch.
           (setq gnus-newsgroup-dependencies
-                (make-vector (length articles) 0))
+                (or gnus-newsgroup-dependencies
+                    (make-vector (length articles) 0)))
 
           (setq gnus-newsgroup-headers
 
           (setq gnus-newsgroup-headers
-                (gnus-get-newsgroup-headers-xover articles nil nil
-                                                  group))
+                (or gnus-newsgroup-headers
+                    (gnus-get-newsgroup-headers-xover articles nil nil
+                                                      group)))
           ;; `gnus-agent-overview-buffer' may be killed for
           ;; timeout reason.  If so, recreate it.
           (gnus-agent-create-buffer)
           ;; `gnus-agent-overview-buffer' may be killed for
           ;; timeout reason.  If so, recreate it.
           (gnus-agent-create-buffer)
@@ -1542,66 +1634,74 @@ of FILE placing the combined headers in nntp-server-buffer."
 
           (unless (and (eq predicate 'gnus-agent-false)
                        (not marked-articles))
 
           (unless (and (eq predicate 'gnus-agent-false)
                        (not marked-articles))
-            (let* ((arts (list nil))
-                   (arts-tail arts)
-                   (chunk-size 0)
-                   (marked-articles marked-articles)
-                   is-marked)
-              (while (setq gnus-headers (pop gnus-newsgroup-headers))
-                (let ((num (mail-header-number gnus-headers)))
-                  ;; Determine if this article was marked for download.
-                  (while (and marked-articles
-                              (cond ((< num (car marked-articles))
-                                     nil)
-                                    ((= num (car marked-articles))
-                                     (setq is-marked t)
-                                     nil)
-                                    (t
-                                     (setq marked-articles
-                                           (cdr marked-articles))))))
-
-                  ;; When this article is marked, or selected by the
-                  ;; predicate, add it to the download list
-                  (when (or is-marked
-                            (let ((gnus-score
-                                   (or (cdr (assq num gnus-newsgroup-scored))
-                                       gnus-summary-default-score)))
-                              (funcall predicate)))
-                    (gnus-agent-append-to-list arts-tail num)
-
-                    ;; When the expected size of the fetched articles
-                    ;; exceeds gnus-agent-max-fetch-size, perform the
-                    ;; fetch.
-                    (when (< gnus-agent-max-fetch-size
-                             (setq chunk-size
-                                   (+ chunk-size
-                                      (mail-header-chars gnus-headers))))
-                      (gnus-agent-fetch-articles group (cdr arts))
-                      (setcdr arts nil)
-                      (setq arts-tail arts)
-                      (setq chunk-size 0)))))
-
-              ;; Fetch all remaining articles
-              (when (cdr arts)
-                (gnus-agent-fetch-articles group (cdr arts)))))
-
-          ;; When some, or all, of the marked articles came
-          ;; from the download mark.  Remove that mark.  I
-          ;; didn't do this earlier as I only want to remove
-          ;; the marks after the fetch is completed.
-
-          (when marked-articles
-            (dolist (mark gnus-agent-download-marks)
-              (when (eq mark 'download)
-                (setq arts (assq mark (gnus-info-marks
-                                       (setq info (gnus-get-info group)))))
-                (when (cdr arts)
-                  (setq marks (delq arts (gnus-info-marks info)))
-                  (gnus-info-set-marks info marks)
-                  (gnus-dribble-enter
-                   (concat "(gnus-group-set-info '"
-                           (gnus-prin1-to-string info)
-                           ")")))))))))))
+            (let ((arts (list nil)))
+              (let ((arts-tail arts)
+                    (alist (gnus-agent-load-alist group))
+                    (marked-articles marked-articles))
+                (while (setq gnus-headers (pop gnus-newsgroup-headers))
+                  (let ((num (mail-header-number gnus-headers)))
+                    ;; Determine if this article is already in the cache
+                    (while (and alist
+                                (> num (caar alist)))
+                      (setq alist (cdr alist)))
+
+                    (unless (and (eq num (caar alist))
+                                 (cdar alist))
+
+                      ;; Determine if this article was marked for download.
+                      (while (and marked-articles
+                                  (> num (car marked-articles)))
+                        (setq marked-articles
+                              (cdr marked-articles)))
+
+                      ;; When this article is marked, or selected by the
+                      ;; predicate, add it to the download list
+                      (when (or (eq num (car marked-articles))
+                                (let ((gnus-score
+                                       (or (cdr (assq num gnus-newsgroup-scored))
+                                           gnus-summary-default-score)))
+                                  (funcall predicate)))
+                        (gnus-agent-append-to-list arts-tail num))))))
+
+              (let (fetched-articles)
+                ;; Fetch all selected articles
+                (setq gnus-newsgroup-undownloaded
+                      (gnus-sorted-ndifference gnus-newsgroup-undownloaded
+                                               (setq fetched-articles (if (cdr arts) (gnus-agent-fetch-articles group (cdr arts)) nil))))
+
+                (let ((unfetched-articles (gnus-sorted-ndifference (cdr arts) fetched-articles)))
+                  (if gnus-newsgroup-active
+                      (progn
+                        (dolist (article marked-articles)
+                          (when (gnus-summary-goto-subject article nil t)
+                            (gnus-summary-set-agent-mark article t)))
+                        (dolist (article fetched-articles)
+                          (if gnus-agent-mark-unread-after-downloaded
+                              (gnus-summary-mark-article article gnus-unread-mark)))
+                        (dolist (article unfetched-articles)
+                          (gnus-summary-mark-article article gnus-canceled-mark)))
+                    ;; When some, or all, of the marked articles came
+                    ;; from the download mark.  Remove that mark.  I
+                    ;; didn't do this earlier as I only want to remove
+                    ;; the marks after the fetch is completed.
+
+                    (dolist (mark gnus-agent-download-marks)
+                      (when (eq mark 'download)
+                        (let ((marked-arts (assq mark (gnus-info-marks
+                                                       (setq info (gnus-get-info group))))))
+                          (when (cdr marked-arts)
+                            (setq marks (delq marked-arts (gnus-info-marks info)))
+                            (gnus-info-set-marks info marks)))))
+                    (let ((read (gnus-info-read (or info (setq info (gnus-get-info group))))))
+                      (gnus-info-set-read info (gnus-add-to-range read unfetched-articles)))
+
+                    (gnus-group-update-group group t)
+                    (sit-for 0)
+
+                    (gnus-dribble-enter
+                     (concat "(gnus-group-set-info '"
+                             (gnus-prin1-to-string info)
+                             ")"))))))))))))
 
 ;;;
 ;;; Agent Category Mode
 
 ;;;
 ;;; Agent Category Mode
@@ -2121,15 +2221,15 @@ FORCE is equivalent to setting gnus-agent-expire-days to zero(0)."
                                     (alist (list nil))
                                     (tail-alist alist))
                                (while dlist
                                     (alist (list nil))
                                     (tail-alist alist))
                                (while dlist
-                                 (let ((new-completed (* 100.0 (/ (setq cnt (1+ cnt)) len))))
+                                 (let ((new-completed (truncate (* 100.0 (/ (setq cnt (1+ cnt)) len)))))
                                    (when (> new-completed completed)
                                      (setq completed new-completed)
                                      (gnus-message 9 "%3d%% completed..."  completed)))
                                    (when (> new-completed completed)
                                      (setq completed new-completed)
                                      (gnus-message 9 "%3d%% completed..."  completed)))
-                                 (let* ((entry (car dlist))
+                                 (let* ((entry          (car dlist))
                                         (article-number (nth 0 entry))
                                         (article-number (nth 0 entry))
-                                        (fetch-date (nth 1 entry))
-                                        (keep (nth 2 entry))
-                                        (marker (nth 3 entry)))
+                                        (fetch-date     (nth 1 entry))
+                                        (keep           (nth 2 entry))
+                                        (marker         (nth 3 entry)))
 
                                    (cond
                                     ;; Kept articles are unread, marked, or special.
 
                                    (cond
                                     ;; Kept articles are unread, marked, or special.
@@ -2180,7 +2280,7 @@ FORCE is equivalent to setting gnus-agent-expire-days to zero(0)."
                                          )
 
                                        (when marker
                                          )
 
                                        (when marker
-                                         (push "NOV entry removed" article)
+                                         (push "NOV entry removed" actions)
                                          (goto-char marker)
                                          (gnus-delete-line))
 
                                          (goto-char marker)
                                          (gnus-delete-line))
 
@@ -2192,6 +2292,8 @@ FORCE is equivalent to setting gnus-agent-expire-days to zero(0)."
                                          (push (format "Removed %s article number from article alist" type) actions))
 
                                        (gnus-message 7 "gnus-agent-expire: Article %d: %s" article-number (mapconcat 'identity actions ", "))))
                                          (push (format "Removed %s article number from article alist" type) actions))
 
                                        (gnus-message 7 "gnus-agent-expire: Article %d: %s" article-number (mapconcat 'identity actions ", "))))
+                                     (t
+                                      (gnus-agent-append-to-list tail-alist (cons article-number fetch-date)))
                                     )
 
                                    ;; Clean up markers as I want to recycle this buffer over several groups.
                                     )
 
                                    ;; Clean up markers as I want to recycle this buffer over several groups.
@@ -2332,9 +2434,10 @@ FORCE is equivalent to setting gnus-agent-expire-days to zero(0)."
                        
                        ;; Get the list of articles that were fetched
                        (goto-char (point-min))
                        
                        ;; Get the list of articles that were fetched
                        (goto-char (point-min))
-                       (ignore-errors 
-                         (while t
-                          (gnus-agent-append-to-list tail-fetched-articles (read (current-buffer)))
+                       (let ((pm (point-max)))
+                         (while (< (point) pm)
+                           (when (looking-at "[0-9]+\t")
+                             (gnus-agent-append-to-list tail-fetched-articles (read (current-buffer))))
                            (forward-line 1)))
                        
                        ;; Clip this list to the headers that will actually be returned
                            (forward-line 1)))
                        
                        ;; Clip this list to the headers that will actually be returned
index c56be74..55c8eb4 100644 (file)
      "^X-Request-PGP:" "^X-Fingerprint:" "^X-WRIEnvto:" "^X-WRIEnvfrom:"
      "^X-Virus-Scanned:" "^X-Delivery-Agent:" "^Posted-Date:" "^X-Gateway:"
      "^X-Local-Origin:" "^X-Local-Destination:" "^X-UserInfo1:"
      "^X-Request-PGP:" "^X-Fingerprint:" "^X-WRIEnvto:" "^X-WRIEnvfrom:"
      "^X-Virus-Scanned:" "^X-Delivery-Agent:" "^Posted-Date:" "^X-Gateway:"
      "^X-Local-Origin:" "^X-Local-Destination:" "^X-UserInfo1:"
-     "^X-Received-Date:" "^X-Hashcash:")
+     "^X-Received-Date:" "^X-Hashcash:" "^Face:")
   "*All headers that start with this regexp will be hidden.
 This variable can also be a list of regexps of headers to be ignored.
 If `gnus-visible-headers' is non-nil, this variable will be ignored."
   "*All headers that start with this regexp will be hidden.
 This variable can also be a list of regexps of headers to be ignored.
 If `gnus-visible-headers' is non-nil, this variable will be ignored."
@@ -758,7 +758,8 @@ displayed by the first non-nil matching CONTENT face."
 
 (defcustom gnus-unbuttonized-mime-types '(".*/.*")
   "List of MIME types that should not be given buttons when rendered inline.
 
 (defcustom gnus-unbuttonized-mime-types '(".*/.*")
   "List of MIME types that should not be given buttons when rendered inline.
-See also `gnus-buttonized-mime-types' which may override this variable."
+See also `gnus-buttonized-mime-types' which may override this variable.
+This variable is only used when `gnus-inhibit-mime-unbuttonizing' is nil."
   :version "21.1"
   :group 'gnus-article-mime
   :type '(repeat regexp))
   :version "21.1"
   :group 'gnus-article-mime
   :type '(repeat regexp))
@@ -767,7 +768,8 @@ See also `gnus-buttonized-mime-types' which may override this variable."
   "List of MIME types that should be given buttons when rendered inline.
 If set, this variable overrides `gnus-unbuttonized-mime-types'.
 To see e.g. security buttons you could set this to
   "List of MIME types that should be given buttons when rendered inline.
 If set, this variable overrides `gnus-unbuttonized-mime-types'.
 To see e.g. security buttons you could set this to
-`(\"multipart/signed\")'."
+`(\"multipart/signed\")'.
+This variable is only used when `gnus-inhibit-mime-unbuttonizing' is nil."
   :version "21.1"
   :group 'gnus-article-mime
   :type '(repeat regexp))
   :version "21.1"
   :group 'gnus-article-mime
   :type '(repeat regexp))
@@ -1222,6 +1224,24 @@ even if you are using Emacs 21+.  It has no effect on XEmacs."
   "Internal variable used to say whether `smiley-mule' is loaded (whether
 smiley functions are not overridden by `smiley').")
 
   "Internal variable used to say whether `smiley-mule' is loaded (whether
 smiley functions are not overridden by `smiley').")
 
+(defcustom gnus-treat-display-face
+  (and (not noninteractive)
+       (or (and (fboundp 'image-type-available-p)
+               (image-type-available-p 'png))
+          (and (featurep 'xemacs)
+               (featurep 'png)))
+       'head)
+  "Display Face headers.
+Valid values are nil, t, `head', `last', an integer or a predicate.
+See Info node `(gnus)Customizing Articles' and Info node
+`(gnus)X-Face' for details."
+  :group 'gnus-article-treat
+  :version "21.1"
+  :link '(custom-manual "(gnus)Customizing Articles")
+  :link '(custom-manual "(gnus)X-Face")
+  :type gnus-article-treat-head-custom)
+(put 'gnus-treat-display-xface 'highlight t)
+
 (defcustom gnus-treat-display-grey-xface
   (and (not noninteractive)
        (or (featurep 'xemacs)
 (defcustom gnus-treat-display-grey-xface
   (and (not noninteractive)
        (or (featurep 'xemacs)
@@ -1431,6 +1451,7 @@ It is a string, such as \"PGP\". If nil, ask user."
     (gnus-treat-date-original gnus-article-date-original)
     (gnus-treat-date-user-defined gnus-article-date-user)
     (gnus-treat-date-iso8601 gnus-article-date-iso8601)
     (gnus-treat-date-original gnus-article-date-original)
     (gnus-treat-date-user-defined gnus-article-date-user)
     (gnus-treat-date-iso8601 gnus-article-date-iso8601)
+    (gnus-treat-display-face gnus-article-display-face)
     (gnus-treat-hide-headers gnus-article-maybe-hide-headers)
     (gnus-treat-hide-boring-headers gnus-article-hide-boring-headers)
     (gnus-treat-hide-signature gnus-article-hide-signature)
     (gnus-treat-hide-headers gnus-article-maybe-hide-headers)
     (gnus-treat-hide-boring-headers gnus-article-hide-boring-headers)
     (gnus-treat-hide-signature gnus-article-hide-signature)
@@ -2042,6 +2063,28 @@ unfolded."
         (forward-line 1)
         (point))))))
 
         (forward-line 1)
         (point))))))
 
+(defun article-display-face ()
+  "Display any Face headers in the header."
+  (interactive)
+  (gnus-with-article-headers
+    (let ((face nil))
+      (save-excursion
+       (when (gnus-buffer-live-p gnus-original-article-buffer)
+         (set-buffer gnus-original-article-buffer)
+         (setq face (message-fetch-field "face"))))
+      (when face
+       (let ((png (gnus-convert-face-to-png face))
+             image)
+         (when png
+           (setq image (gnus-create-image png 'png t))
+           (gnus-article-goto-header "from")
+           (when (bobp)
+             (insert "From: [no `from' set]\n")
+             (forward-char -17))
+           (gnus-add-wash-type 'face)
+           (gnus-add-image 'face image)
+           (gnus-put-image image)))))))
+
 (defun article-display-x-face (&optional force)
   "Look for an X-Face header and display it if present."
   (interactive (list 'force))
 (defun article-display-x-face (&optional force)
   "Look for an X-Face header and display it if present."
   (interactive (list 'force))
@@ -3525,6 +3568,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is
      article-remove-cr
      article-remove-leading-whitespace
      article-display-x-face
      article-remove-cr
      article-remove-leading-whitespace
      article-display-x-face
+     article-display-face
      article-de-quoted-unreadable
      article-de-base64-unreadable
      article-decode-HZ
      article-de-quoted-unreadable
      article-de-base64-unreadable
      article-decode-HZ
@@ -4671,9 +4715,10 @@ If no internal viewer is available, use an external viewer."
          ;; We have to do this since selecting the window
          ;; may change the point.  So we set the window point.
          (set-window-point window point)))
          ;; We have to do this since selecting the window
          ;; may change the point.  So we set the window point.
          (set-window-point window point)))
-      (let* ((handles (or ihandles (mm-dissect-buffer
-                                   nil gnus-article-loose-mime)
-                         (mm-uu-dissect)))
+      (let* ((handles (or ihandles
+                         (mm-dissect-buffer nil gnus-article-loose-mime)
+                         (and gnus-article-emulate-mime
+                              (mm-uu-dissect))))
             buffer-read-only handle name type b e display)
        (when (and (not ihandles)
                   (not gnus-displaying-mime))
             buffer-read-only handle name type b e display)
        (when (and (not ihandles)
                   (not gnus-displaying-mime))
@@ -5610,7 +5655,7 @@ If given a prefix, show the hidden text instead."
     "\C-c\C-f\C-k" message-goto-keywords
     "\C-c\C-f\C-u" message-goto-summary
     "\C-c\C-f\C-i" message-insert-or-toggle-importance
     "\C-c\C-f\C-k" message-goto-keywords
     "\C-c\C-f\C-u" message-goto-summary
     "\C-c\C-f\C-i" message-insert-or-toggle-importance
-    "\C-c\C-f\C-a" message-gen-unsubscribed-mft
+    "\C-c\C-f\C-a" message-generate-unsubscribed-mail-followup-to
     "\C-c\C-b" message-goto-body
     "\C-c\C-i" message-goto-signature
 
     "\C-c\C-b" message-goto-body
     "\C-c\C-i" message-goto-signature
 
index 927abba..ca999e0 100644 (file)
@@ -672,7 +672,8 @@ See also the documentation for `gnus-article-highlight-citation'."
              (and (>= (gnus-overlay-end overlay) (point-min))
                   (<= (gnus-overlay-end overlay) (point-max))))
       (setq gnus-cite-overlay-list (delete overlay gnus-cite-overlay-list))
              (and (>= (gnus-overlay-end overlay) (point-min))
                   (<= (gnus-overlay-end overlay) (point-max))))
       (setq gnus-cite-overlay-list (delete overlay gnus-cite-overlay-list))
-      (gnus-delete-overlay overlay))))
+      (ignore-errors
+       (gnus-delete-overlay overlay)))))
 
 (defun gnus-cite-parse-wrapper ()
   ;; Wrap chopped gnus-cite-parse.
 
 (defun gnus-cite-parse-wrapper ()
   ;; Wrap chopped gnus-cite-parse.
index fa2b54f..53499f3 100644 (file)
   :group 'gnus-fun
   :type 'string)
 
   :group 'gnus-fun
   :type 'string)
 
+(defcustom gnus-convert-image-to-face-command "djpeg %s | ppmnorm | pnmscale -width 48 -height 48 | ppmquant %d | pnmtopng"
+  "Command for converting a GIF to an X-Face."
+  :group 'gnus-fun
+  :type 'string)
+
 (defun gnus-shell-command-to-string (command)
   "Like `shell-command-to-string' except not mingling ERROR."
   (with-output-to-string
 (defun gnus-shell-command-to-string (command)
   "Like `shell-command-to-string' except not mingling ERROR."
   (with-output-to-string
@@ -74,6 +79,50 @@ Output to the current buffer, replace text, and don't mingle error."
      (format gnus-convert-image-to-x-face-command
             (shell-quote-argument file)))))
 
      (format gnus-convert-image-to-x-face-command
             (shell-quote-argument file)))))
 
+(defun gnus-face-from-file (file)
+  "Return an Face header based on an image file."
+  (interactive "fImage file name:" )
+  (when (file-exists-p file)
+    (let ((done nil)
+         (attempt "")
+         (step 72)
+         (quant 16))
+      (while (and (not done)
+                 (> quant 1))
+       (setq attempt
+             (gnus-shell-command-to-string
+              (format gnus-convert-image-to-face-command
+                      (shell-quote-argument file)
+                      quant)))
+       (if (> (length attempt) 740)
+           (progn
+             (setq quant (- quant 2))
+             (message "Length %d; trying quant %d"
+                      (length attempt) quant))
+         (setq done t)))
+      (if done
+         (mm-with-unibyte-buffer       
+           (insert attempt)
+           (base64-encode-region (point-min) (point-max))
+           (goto-char (point-min))
+           (while (search-forward "\n" nil t)
+             (replace-match ""))
+           (goto-char (point-min))
+           (while (> (- (point-max) (point))
+                     step)
+             (forward-char step)
+             (insert "\n ")
+             (setq step 76))
+           (buffer-string))
+       nil))))
+
+;;;###autoload
+(defun gnus-convert-face-to-png (face)
+  (mm-with-unibyte-buffer
+    (insert face)
+    (base64-decode-region (point-min) (point-max))
+    (buffer-string)))
+
 (defun gnus-convert-image-to-gray-x-face (file depth)
   (let* ((mapfile (mm-make-temp-file (expand-file-name "gnus."
                                                       mm-tmp-directory)))
 (defun gnus-convert-image-to-gray-x-face (file depth)
   (let* ((mapfile (mm-make-temp-file (expand-file-name "gnus."
                                                       mm-tmp-directory)))
index 6f9ec6e..c653292 100644 (file)
@@ -156,6 +156,7 @@ with some simple extensions.
 %i    Number of ticked and dormant (integer)
 %T    Number of ticked articles (integer)
 %R    Number of read articles (integer)
 %i    Number of ticked and dormant (integer)
 %T    Number of ticked articles (integer)
 %R    Number of read articles (integer)
+%U    Number of unseen articles (integer)
 %t    Estimated total number of articles (integer)
 %y    Number of unread, unticked articles (integer)
 %G    Group name (string)
 %t    Estimated total number of articles (integer)
 %y    Number of unread, unticked articles (integer)
 %G    Group name (string)
@@ -471,6 +472,7 @@ simple manner.")
                   (gnus-range-length (cdr (assq 'tick gnus-tmp-marked))))))
              (t number)) ?s)
     (?R gnus-tmp-number-of-read ?s)
                   (gnus-range-length (cdr (assq 'tick gnus-tmp-marked))))))
              (t number)) ?s)
     (?R gnus-tmp-number-of-read ?s)
+    (?U (gnus-number-of-unseen-articles-in-group gnus-tmp-group) ?d)
     (?t gnus-tmp-number-total ?d)
     (?y gnus-tmp-number-of-unread ?s)
     (?I (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) ?d)
     (?t gnus-tmp-number-total ?d)
     (?y gnus-tmp-number-of-unread ?s)
     (?I (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) ?d)
@@ -1348,6 +1350,18 @@ if it is a string, only list groups matching REGEXP."
         nil)
        (gnus-method-simplify (gnus-find-method-for-group group))))))
 
         nil)
        (gnus-method-simplify (gnus-find-method-for-group group))))))
 
+(defun gnus-number-of-unseen-articles-in-group (group)
+  (let* ((info (nth 2 (gnus-group-entry group)))
+        (marked (gnus-info-marks info))
+        (seen (cdr (assq 'seen marked)))
+        (active (gnus-active group)))
+    (if (not active)
+       0
+      (length (gnus-uncompress-range
+              (gnus-range-difference
+               (gnus-range-difference (list active) (gnus-info-read info))
+               seen))))))
+
 (defun gnus-group-insert-group-line (gnus-tmp-group gnus-tmp-level
                                                    gnus-tmp-marked number
                                                    gnus-tmp-method)
 (defun gnus-group-insert-group-line (gnus-tmp-group gnus-tmp-level
                                                    gnus-tmp-marked number
                                                    gnus-tmp-method)
@@ -2505,7 +2519,9 @@ If SOLID (the prefix), create a solid group."
                  (nnweb-type ,(intern type))
                  (nnweb-ephemeral-p t))))
     (if solid
                  (nnweb-type ,(intern type))
                  (nnweb-ephemeral-p t))))
     (if solid
-       (gnus-group-make-group group "nnweb" "" `(,(intern type) ,search))
+       (progn
+         (gnus-pull 'nnweb-ephemeral-p method)
+         (gnus-group-make-group group method))
       (gnus-group-read-ephemeral-group
        group method t
        (cons (current-buffer)
       (gnus-group-read-ephemeral-group
        group method t
        (cons (current-buffer)
@@ -3072,7 +3088,8 @@ or nil if no action could be taken."
       num)))
 
 (defun gnus-group-expire-articles (&optional n)
       num)))
 
 (defun gnus-group-expire-articles (&optional n)
-  "Expire all expirable articles in the current newsgroup."
+  "Expire all expirable articles in the current newsgroup.
+Uses the process/prefix convention."
   (interactive "P")
   (let ((groups (gnus-group-process-prefix n))
        group)
   (interactive "P")
   (let ((groups (gnus-group-process-prefix n))
        group)
index 74d68d0..129a6e3 100644 (file)
@@ -508,10 +508,10 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned."
           (gnus-get-function gnus-command-method 'request-expire-articles)
           articles (gnus-group-real-name group) (nth 1 gnus-command-method)
           force)))
           (gnus-get-function gnus-command-method 'request-expire-articles)
           articles (gnus-group-real-name group) (nth 1 gnus-command-method)
           force)))
-    (when (and gnus-agent gnus-agent-cache
-              (gnus-sorted-difference articles not-deleted))
-      (gnus-agent-expire (gnus-sorted-difference articles not-deleted)
-                        group 'force))
+    (when (and gnus-agent gnus-agent-cache (gnus-agent-method-p gnus-command-method))
+      (let ((expired-articles (gnus-sorted-difference articles not-deleted)))
+        (when expired-articles
+          (gnus-agent-expire expired-articles group 'force))))
     not-deleted))
 
 (defun gnus-request-move-article (article group server accept-function &optional last)
     not-deleted))
 
 (defun gnus-request-move-article (article group server accept-function &optional last)
@@ -519,7 +519,7 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned."
         (result (funcall (gnus-get-function gnus-command-method 'request-move-article)
                          article (gnus-group-real-name group)
                          (nth 1 gnus-command-method) accept-function last)))
         (result (funcall (gnus-get-function gnus-command-method 'request-move-article)
                          article (gnus-group-real-name group)
                          (nth 1 gnus-command-method) accept-function last)))
-    (when (and result gnus-agent gnus-agent-cache)
+    (when (and result gnus-agent gnus-agent-cache (gnus-agent-method-p gnus-command-method))
       (gnus-agent-expire (list article) group 'force))
     result))
 
       (gnus-agent-expire (list article) group 'force))
     result))
 
index ca39927..a672c03 100644 (file)
@@ -1,5 +1,5 @@
 ;;; gnus-msg.el --- mail and post interface for Semi-gnus
 ;;; gnus-msg.el --- mail and post interface for Semi-gnus
-;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
@@ -388,7 +388,7 @@ Thank you for your help in stamping out bugs.
 (defun gnus-inews-make-draft ()
   `(lambda ()
      (gnus-inews-make-draft-meta-information
 (defun gnus-inews-make-draft ()
   `(lambda ()
      (gnus-inews-make-draft-meta-information
-      ,gnus-newsgroup-name ,gnus-article-reply)))
+      ,gnus-newsgroup-name ',gnus-article-reply)))
 
 (defvar gnus-article-reply nil)
 (defmacro gnus-setup-message (config &rest forms)
 
 (defvar gnus-article-reply nil)
 (defmacro gnus-setup-message (config &rest forms)
@@ -619,7 +619,8 @@ a news."
           ""))
        ;; make sure last viewed article doesn't affect posting styles:
        (gnus-article-copy))
           ""))
        ;; make sure last viewed article doesn't affect posting styles:
        (gnus-article-copy))
-    (gnus-post-news 'post gnus-newsgroup-name)))
+    (gnus-post-news 'post gnus-newsgroup-name nil nil nil nil
+                   (string= gnus-newsgroup-name ""))))
 
 (defun gnus-summary-mail-other-window (&optional arg)
   "Start composing a mail in another window.
 
 (defun gnus-summary-mail-other-window (&optional arg)
   "Start composing a mail in another window.
@@ -1704,17 +1705,15 @@ The source file has to be in the Emacs load path."
       (insert ";----------------- Environment follows ------------------\n\n"))
     (while olist
       (if (boundp (car olist))
       (insert ";----------------- Environment follows ------------------\n\n"))
     (while olist
       (if (boundp (car olist))
-         (condition-case ()
-             (pp `(setq ,(car olist)
-                        ,(if (or (consp (setq sym (symbol-value (car olist))))
-                                 (and (symbolp sym)
-                                      (not (or (eq sym nil)
-                                               (eq sym t)))))
-                             (list 'quote (symbol-value (car olist)))
-                           (symbol-value (car olist))))
-                 (current-buffer))
-           (error
-            (format "(setq %s 'whatever)\n" (car olist))))
+         (ignore-errors
+           (pp `(setq ,(car olist)
+                      ,(if (or (consp (setq sym (symbol-value (car olist))))
+                               (and (symbolp sym)
+                                    (not (or (eq sym nil)
+                                             (eq sym t)))))
+                           (list 'quote (symbol-value (car olist)))
+                         (symbol-value (car olist))))
+               (current-buffer)))
        (insert ";; (makeunbound '" (symbol-name (car olist)) ")\n"))
       (setq olist (cdr olist)))
     ;; Remove any control chars - they seem to cause trouble for some
        (insert ";; (makeunbound '" (symbol-name (car olist)) ")\n"))
       (setq olist (cdr olist)))
     ;; Remove any control chars - they seem to cause trouble for some
@@ -1810,6 +1809,7 @@ this is a reply."
                              group (gnus-status-message method))
                (sit-for 2))
              (when (and group-art
                              group (gnus-status-message method))
                (sit-for 2))
              (when (and group-art
+                        (gnus-alive-p)
                         (or gnus-gcc-mark-as-read
                             gnus-inews-mark-gcc-as-read))
                (gnus-group-mark-article-read group (cdr group-art)))
                         (or gnus-gcc-mark-as-read
                             gnus-inews-mark-gcc-as-read))
                (gnus-group-mark-article-read group (cdr group-art)))
@@ -2017,7 +2017,9 @@ this is a reply."
                           (let ((value ,(cdr result)))
                             (when value
                               (message-goto-eoh)
                           (let ((value ,(cdr result)))
                             (when value
                               (message-goto-eoh)
-                              (insert ,header ": " value "\n"))))))))
+                              (insert ,header ": " value)
+                              (unless (bolp)
+                                (insert "\n")))))))))
                  nil 'local))
       (when (or name address)
        (add-hook 'message-setup-hook
                  nil 'local))
       (when (or name address)
        (add-hook 'message-setup-hook
index 0002f80..087871e 100644 (file)
@@ -1758,7 +1758,8 @@ score in `gnus-newsgroup-scored' by SCORE."
                        (setq found t)
                        (when trace
                          (push
                        (setq found t)
                        (when trace
                          (push
-                          (cons (car-safe (rassq alist gnus-score-cache)) kill)
+                          (cons (car-safe (rassq alist gnus-score-cache))
+                                kill)
                           gnus-score-trace)))
                      ;; Update expire date
                      (unless trace
                           gnus-score-trace)))
                      ;; Update expire date
                      (unless trace
@@ -1864,6 +1865,12 @@ score in `gnus-newsgroup-scored' by SCORE."
                (setq found (setq arts (get-text-property (point) 'articles)))
                ;; Found a match, update scores.
                (while (setq art (pop arts))
                (setq found (setq arts (get-text-property (point) 'articles)))
                ;; Found a match, update scores.
                (while (setq art (pop arts))
+                 (setcdr art (+ score (cdr art)))
+                 (when trace
+                   (push (cons
+                          (car-safe (rassq alist gnus-score-cache))
+                          kill)
+                         gnus-score-trace))
                  (when (setq new (gnus-score-add-followups
                                   (car art) score all-scores thread))
                    (push new news)))))
                  (when (setq new (gnus-score-add-followups
                                   (car art) score all-scores thread))
                    (push new news)))))
index 2fb82f9..106160c 100644 (file)
@@ -226,7 +226,7 @@ This is returned as a string."
          (when spec
            (push (concat "if " (gnus-sieve-test spec) " {\n"
                          "\tfileinto \"" (gnus-group-real-name group) "\";\n"
          (when spec
            (push (concat "if " (gnus-sieve-test spec) " {\n"
                          "\tfileinto \"" (gnus-group-real-name group) "\";\n"
-                         (if gnus-sieve-crosspost
+                         (if crosspost
                              ""
                            "\tstop;\n")
                          "}")
                              ""
                            "\tstop;\n")
                          "}")
index 237505e..e6f2c7d 100644 (file)
@@ -440,14 +440,14 @@ characters when given a pad value."
   ;; them will have the balloon-help text property.
   (let ((case-fold-search nil))
     (if (string-match
   ;; them will have the balloon-help text property.
   (let ((case-fold-search nil))
     (if (string-match
-        "\\`\\(.*\\)%[0-9]?[{(«]\\(.*\\)%[0-9]?[»})]\\(.*\n?\\)\\'\\|%[-0-9]*="
+        "\\`\\(.*\\)%[0-9]?[{(«]\\(.*\\)%[0-9]?[»})]\\(.*\n?\\)\\'\\|%[-0-9]*=\\|%[-0-9]*\\*"
         format)
        (gnus-parse-complex-format format spec-alist)
       ;; This is a simple format.
       (gnus-parse-simple-format format spec-alist insert))))
 
 (defun gnus-parse-complex-format (format spec-alist)
         format)
        (gnus-parse-complex-format format spec-alist)
       ;; This is a simple format.
       (gnus-parse-simple-format format spec-alist insert))))
 
 (defun gnus-parse-complex-format (format spec-alist)
-  (let (found-C)
+  (let ((cursor-spec nil))
     (save-excursion
       (gnus-set-work-buffer)
       (insert format)
     (save-excursion
       (gnus-set-work-buffer)
       (insert format)
@@ -476,9 +476,9 @@ characters when given a pad value."
       ;; Convert point position commands.
       (goto-char (point-min))
       (let ((case-fold-search nil))
       ;; Convert point position commands.
       (goto-char (point-min))
       (let ((case-fold-search nil))
-       (while (re-search-forward "%\\([-0-9]+\\)?C" nil t)
+       (while (re-search-forward "%\\([-0-9]+\\)?\\*" nil t)
          (replace-match "\"(point)\"" t t)
          (replace-match "\"(point)\"" t t)
-         (setq found-C t)))
+         (setq cursor-spec t)))
       ;; Convert TAB commands.
       (goto-char (point-min))
       (while (re-search-forward "%\\([-0-9]+\\)=" nil t)
       ;; Convert TAB commands.
       (goto-char (point-min))
       (while (re-search-forward "%\\([-0-9]+\\)=" nil t)
@@ -486,7 +486,7 @@ characters when given a pad value."
       ;; Convert the buffer into the spec.
       (goto-char (point-min))
       (let ((form (read (current-buffer))))
       ;; Convert the buffer into the spec.
       (goto-char (point-min))
       (let ((form (read (current-buffer))))
-       (if found-C
+       (if cursor-spec
            `(let (gnus-position)
               ,@(gnus-complex-form-to-spec form spec-alist)
               (if gnus-position
            `(let (gnus-position)
               ,@(gnus-complex-form-to-spec form spec-alist)
               (if gnus-position
index d2b6022..2c846b9 100644 (file)
@@ -1,5 +1,5 @@
 ;;; gnus-srvr.el --- virtual server support for Gnus
 ;;; gnus-srvr.el --- virtual server support for Gnus
-;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
@@ -721,22 +721,22 @@ The following commands are available:
            (delete-matching-lines gnus-ignored-newsgroups))
          (while (not (eobp))
            (ignore-errors
            (delete-matching-lines gnus-ignored-newsgroups))
          (while (not (eobp))
            (ignore-errors
-            (push (cons
-                   (if (eq (char-after) ?\")
-                       (read cur)
-                     (let ((p (point)) (name ""))
-                       (skip-chars-forward "^ \t\\\\")
-                       (setq name (buffer-substring p (point)))
-                       (while (eq (char-after) ?\\)
-                         (setq p (1+ (point)))
-                         (forward-char 2)
-                         (skip-chars-forward "^ \t\\\\")
-                         (setq name (concat name (buffer-substring
-                                                  p (point)))))
-                       name))
-                   (let ((last (read cur)))
-                     (cons (read cur) last)))
-                  groups))
+             (push (cons
+                    (if (eq (char-after) ?\")
+                        (read cur)
+                      (let ((p (point)) (name ""))
+                        (skip-chars-forward "^ \t\\\\")
+                        (setq name (buffer-substring p (point)))
+                        (while (eq (char-after) ?\\)
+                          (setq p (1+ (point)))
+                          (forward-char 2)
+                          (skip-chars-forward "^ \t\\\\")
+                          (setq name (concat name (buffer-substring
+                                                   p (point)))))
+                        name))
+                    (let ((last (read cur)))
+                      (cons (read cur) last)))
+                   groups))
            (forward-line))))
       (setq groups (sort groups
                         (lambda (l1 l2)
            (forward-line))))
       (setq groups (sort groups
                         (lambda (l1 l2)
@@ -767,27 +767,27 @@ The following commands are available:
               (format
                "Gnus: %%b {%s:%s}" (car method) (cadr method))))
        (let ((buffer-read-only nil)
               (format
                "Gnus: %%b {%s:%s}" (car method) (cadr method))))
        (let ((buffer-read-only nil)
-             charset
+             name
              (prefix (let ((gnus-select-method orig-select-method))
                        (gnus-group-prefixed-name "" method))))
              (prefix (let ((gnus-select-method orig-select-method))
                        (gnus-group-prefixed-name "" method))))
-         (dolist (group groups)
-           (setq charset (gnus-group-name-charset method (car group)))
+         (while (setq group (pop groups))
            (gnus-add-text-properties
             (point)
             (prog1 (1+ (point))
               (insert
                (format "%c%7d: %s\n"
                        (let ((level (gnus-group-level
            (gnus-add-text-properties
             (point)
             (prog1 (1+ (point))
               (insert
                (format "%c%7d: %s\n"
                        (let ((level (gnus-group-level
-                                     (concat prefix (car group)))))
+                                     (concat prefix (setq name (car group))))))
                          (cond
                           ((<= level gnus-level-subscribed) ? )
                           ((<= level gnus-level-unsubscribed) ?U)
                           ((= level gnus-level-zombie) ?Z)
                           (t ?K)))
                        (max 0 (- (1+ (cddr group)) (cadr group)))
                          (cond
                           ((<= level gnus-level-subscribed) ? )
                           ((<= level gnus-level-unsubscribed) ?U)
                           ((= level gnus-level-zombie) ?Z)
                           (t ?K)))
                        (max 0 (- (1+ (cddr group)) (cadr group)))
-                       (gnus-group-name-decode (car group) charset))))
-            (list 'gnus-group (car group)))
-           (setq groups (cdr groups))))
+                       (decode-coding-string
+                        name
+                        (inline (gnus-group-name-charset method name))))))
+            (list 'gnus-group name))))
        (switch-to-buffer (current-buffer)))
       (goto-char (point-min))
       (gnus-group-position-point)
        (switch-to-buffer (current-buffer)))
       (goto-char (point-min))
       (gnus-group-position-point)
index 9ea1efc..7329a7c 100644 (file)
@@ -57,6 +57,9 @@
 (autoload 'gnus-article-outlook-deuglify-article "deuglify"
   "Deuglify broken Outlook (Express) articles and redisplay."
   t)
 (autoload 'gnus-article-outlook-deuglify-article "deuglify"
   "Deuglify broken Outlook (Express) articles and redisplay."
   t)
+(autoload 'gnus-outlook-unwrap-lines "deuglify" nil t)
+(autoload 'gnus-outlook-repair-attribution "deuglify" nil t)
+(autoload 'gnus-outlook-rearrange-citation "deuglify" nil t)
 
 (defcustom gnus-kill-summary-on-exit t
   "*If non-nil, kill the summary buffer when you exit from it.
 
 (defcustom gnus-kill-summary-on-exit t
   "*If non-nil, kill the summary buffer when you exit from it.
@@ -120,7 +123,7 @@ given by the `gnus-summary-same-subject' variable.)"
                 (const adopt)
                 (const empty)))
 
                 (const adopt)
                 (const empty)))
 
-(defcustom gnus-summary-make-false-root-always t
+(defcustom gnus-summary-make-false-root-always nil
   "Always make a false dummy root."
   :group 'gnus-thread
   :type 'boolean)
   "Always make a false dummy root."
   :group 'gnus-thread
   :type 'boolean)
@@ -820,6 +823,7 @@ following hook:
 (defcustom gnus-select-article-hook nil
   "*A hook called when an article is selected."
   :group 'gnus-summary-choose
 (defcustom gnus-select-article-hook nil
   "*A hook called when an article is selected."
   :group 'gnus-summary-choose
+  :options '(gnus-agent-fetch-selected-article)
   :type 'hook)
 
 (defcustom gnus-visual-mark-article-hook
   :type 'hook)
 
 (defcustom gnus-visual-mark-article-hook
@@ -888,11 +892,11 @@ automatically when it is selected."
   '(((eq mark gnus-canceled-mark)
      . gnus-summary-cancelled-face)
     ((and uncached (> score default-high))
   '(((eq mark gnus-canceled-mark)
      . gnus-summary-cancelled-face)
     ((and uncached (> score default-high))
-     . gnus-summary-high-uncached-face)
+     . gnus-summary-high-undownloaded-face)
     ((and uncached (< score default-low))
     ((and uncached (< score default-low))
-     . gnus-summary-low-uncached-face)
+     . gnus-summary-low-undownloaded-face)
     (uncached
     (uncached
-     . gnus-summary-normal-uncached-face)
+     . gnus-summary-normal-undownloaded-face)
     ((and (> score default-high)
          (or (eq mark gnus-dormant-mark)
              (eq mark gnus-ticked-mark)))
     ((and (> score default-high)
          (or (eq mark gnus-dormant-mark)
              (eq mark gnus-ticked-mark)))
@@ -1085,6 +1089,14 @@ the MIME-Version header is missed."
   :type 'boolean
   :group 'gnus-article)
 
   :type 'boolean
   :group 'gnus-article)
 
+(defcustom gnus-article-emulate-mime t
+  "If non-nil, use MIME emulation for uuencode and the like.
+This means that Gnus will search message bodies for text that look
+like uuencoded bits, yEncoded bits, and so on, and present that using
+the normal Gnus MIME machinery."
+  :type 'boolean
+  :group 'gnus-article)
+
 ;;; Internal variables
 
 (defvar gnus-summary-display-cache nil)
 ;;; Internal variables
 
 (defvar gnus-summary-display-cache nil)
@@ -1380,7 +1392,12 @@ buffers. For example:
 ")
 
 ;; Byte-compiler warning.
 ")
 
 ;; Byte-compiler warning.
-(eval-when-compile (defvar gnus-article-mode-map))
+;(eval-when-compile (defvar gnus-article-mode-map))
+(eval-when-compile
+  (let ((features (cons 'gnus-sum features)))
+    (require 'gnus)
+    (require 'gnus-agent)
+    (require 'gnus-art)))
 
 ;; Subject simplification.
 
 
 ;; Subject simplification.
 
@@ -1796,7 +1813,14 @@ increase the score of each group you read."
     "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
     "p" gnus-article-verify-x-pgp-sig
     "d" gnus-article-treat-dumbquotes
     "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
     "p" gnus-article-verify-x-pgp-sig
     "d" gnus-article-treat-dumbquotes
-    "k" gnus-article-outlook-deuglify-article)
+    "k" gnus-article-outlook-deuglify-article) ;; mnemonic: outloo*k*
+
+  (gnus-define-keys (gnus-summary-wash-deuglify-map "Y" gnus-summary-wash-map)
+    ;; mnemonic: deuglif*Y*
+    "u" gnus-outlook-unwrap-lines
+    "a" gnus-outlook-repair-attribution
+    "c" gnus-outlook-rearrange-citation
+    "f" gnus-article-outlook-deuglify-article) ;; mnemonic: full deuglify
 
   (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
     "a" gnus-article-hide
 
   (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
     "a" gnus-article-hide
@@ -2094,7 +2118,12 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs))))
              ["URLs" gnus-article-unsplit-urls t]
              ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
              ["HZ" gnus-article-decode-HZ t]
              ["URLs" gnus-article-unsplit-urls t]
              ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
              ["HZ" gnus-article-decode-HZ t]
-             ["OutlooK deuglify" gnus-article-outlook-deuglify-article t]
+             ("(Outlook) Deuglify"
+              ["Unwrap lines" gnus-outlook-unwrap-lines t]
+              ["Repair attribution" gnus-outlook-repair-attribution t]
+              ["Rearrange citation" gnus-outlook-rearrange-citation t]
+              ["Full (Outlook) deuglify"
+               gnus-article-outlook-deuglify-article t])
              )
             ("Output"
              ["Save in default format" gnus-summary-save-article
              )
             ("Output"
              ["Save in default format" gnus-summary-save-article
@@ -2177,6 +2206,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs))))
     (easy-menu-define
      gnus-summary-thread-menu gnus-summary-mode-map ""
      '("Threads"
     (easy-menu-define
      gnus-summary-thread-menu gnus-summary-mode-map ""
      '("Threads"
+       ["Find all messages in thread" gnus-summary-refer-thread t]
        ["Toggle threading" gnus-summary-toggle-threads t]
        ["Hide threads" gnus-summary-hide-all-threads t]
        ["Show threads" gnus-summary-show-all-threads t]
        ["Toggle threading" gnus-summary-toggle-threads t]
        ["Hide threads" gnus-summary-hide-all-threads t]
        ["Show threads" gnus-summary-show-all-threads t]
@@ -2857,6 +2887,7 @@ article number."
 This is all marks except unread, ticked, dormant, and expirable."
   (not (or (= mark gnus-unread-mark)
           (= mark gnus-ticked-mark)
 This is all marks except unread, ticked, dormant, and expirable."
   (not (or (= mark gnus-unread-mark)
           (= mark gnus-ticked-mark)
+          (= mark gnus-spam-mark)
           (= mark gnus-dormant-mark)
           (= mark gnus-expirable-mark))))
 
           (= mark gnus-dormant-mark)
           (= mark gnus-expirable-mark))))
 
@@ -3093,7 +3124,7 @@ buffer that was in action when the last article was fetched."
     (let ((gnus-replied-mark 129)
          (gnus-score-below-mark 130)
          (gnus-score-over-mark 130)
     (let ((gnus-replied-mark 129)
          (gnus-score-below-mark 130)
          (gnus-score-over-mark 130)
-         (gnus-downloaded-mark 131)
+         (gnus-undownloaded-mark 131)
          (spec gnus-summary-line-format-spec)
          gnus-visual pos)
       (save-excursion
          (spec gnus-summary-line-format-spec)
          gnus-visual pos)
       (save-excursion
@@ -3104,7 +3135,7 @@ buffer that was in action when the last article was fetched."
           (make-full-mail-header 0 "" "nobody"
                                  "05 Apr 2001 23:33:09 +0400"
                                  "" "" 0 0 "" nil)
           (make-full-mail-header 0 "" "nobody"
                                  "05 Apr 2001 23:33:09 +0400"
                                  "" "" 0 0 "" nil)
-          0 nil nil 128 t nil "" nil 1)
+          0 nil t 128 t nil "" nil 1)
          (goto-char (point-min))
          (setq pos (list (cons 'unread (and (search-forward "\200" nil t)
                                             (- (point) (point-min) 1)))))
          (goto-char (point-min))
          (setq pos (list (cons 'unread (and (search-forward "\200" nil t)
                                             (- (point) (point-min) 1)))))
@@ -3497,8 +3528,9 @@ If SHOW-ALL is non-nil, already read articles are also listed."
            (progn
              (gnus-configure-windows 'summary)
              (let ((art (gnus-summary-article-number)))
            (progn
              (gnus-configure-windows 'summary)
              (let ((art (gnus-summary-article-number)))
-               (unless (or (memq art gnus-newsgroup-undownloaded)
-                           (memq art gnus-newsgroup-downloadable))
+               (unless (and (not gnus-plugged)
+                            (or (memq art gnus-newsgroup-undownloaded)
+                                (memq art gnus-newsgroup-downloadable)))
                  (gnus-summary-goto-article art))))
          ;; Don't select any articles.
          (gnus-summary-position-point)
                  (gnus-summary-goto-article art))))
          ;; Don't select any articles.
          (gnus-summary-position-point)
@@ -3515,7 +3547,8 @@ If SHOW-ALL is non-nil, already read articles are also listed."
        ;; Mark this buffer as "prepared".
        (setq gnus-newsgroup-prepared t)
        (gnus-run-hooks 'gnus-summary-prepared-hook)
        ;; Mark this buffer as "prepared".
        (setq gnus-newsgroup-prepared t)
        (gnus-run-hooks 'gnus-summary-prepared-hook)
-       (gnus-group-update-group group)
+       (unless (gnus-ephemeral-group-p group)
+         (gnus-group-update-group group))
        t)))))
 
 (defun gnus-summary-auto-select-subject ()
        t)))))
 
 (defun gnus-summary-auto-select-subject ()
@@ -5572,7 +5605,8 @@ The resulting hash table is returned, or nil if no Xrefs were found."
        ;; Update the number of unread articles.
        (setcar entry num)
        ;; Update the group buffer.
        ;; Update the number of unread articles.
        (setcar entry num)
        ;; Update the group buffer.
-       (gnus-group-update-group group t)))))
+       (unless (gnus-ephemeral-group-p group)
+         (gnus-group-update-group group t))))))
 
 (defvar gnus-newsgroup-none-id 0)
 
 
 (defvar gnus-newsgroup-none-id 0)
 
@@ -6394,7 +6428,10 @@ If FORCE (the prefix), also save the .newsrc file(s)."
        (set-buffer gnus-group-buffer)
        (gnus-summary-clear-local-variables)
        (let ((gnus-summary-local-variables gnus-newsgroup-variables))
        (set-buffer gnus-group-buffer)
        (gnus-summary-clear-local-variables)
        (let ((gnus-summary-local-variables gnus-newsgroup-variables))
-         (gnus-summary-clear-local-variables)))
+         (gnus-summary-clear-local-variables))
+       ;; Return to group mode buffer.
+       (when (eq mode 'gnus-summary-mode)
+         (gnus-kill-buffer buf)))
       (setq gnus-current-select-method gnus-select-method)
       (pop-to-buffer gnus-group-buffer)
       (if (not quit-config)
       (setq gnus-current-select-method gnus-select-method)
       (pop-to-buffer gnus-group-buffer)
       (if (not quit-config)
@@ -6409,9 +6446,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
              (set-window-start (selected-window) (point))
              (goto-char group-point)))
        (gnus-handle-ephemeral-exit quit-config))
              (set-window-start (selected-window) (point))
              (goto-char group-point)))
        (gnus-handle-ephemeral-exit quit-config))
-      ;; Return to group mode buffer.
-      (when (eq mode 'gnus-summary-mode)
-       (gnus-kill-buffer buf))
       ;; Clear the current group name.
       (unless quit-config
        (setq gnus-newsgroup-name nil)))))
       ;; Clear the current group name.
       (unless quit-config
        (setq gnus-newsgroup-name nil)))))
@@ -6458,7 +6492,8 @@ If FORCE (the prefix), also save the .newsrc file(s)."
       (gnus-configure-windows 'group 'force)
       ;; Clear the current group name.
       (setq gnus-newsgroup-name nil)
       (gnus-configure-windows 'group 'force)
       ;; Clear the current group name.
       (setq gnus-newsgroup-name nil)
-      (gnus-group-update-group group)
+      (unless (gnus-ephemeral-group-p group)
+       (gnus-group-update-group group))
       (when (equal (gnus-group-group-name) group)
        (gnus-group-next-unread-group 1))
       (when quit-config
       (when (equal (gnus-group-group-name) group)
        (gnus-group-next-unread-group 1))
       (when quit-config
@@ -6708,7 +6743,8 @@ Returns the article selected or nil if there are no unread articles."
        (let ((data gnus-newsgroup-data))
          (while (and data
                      (and (not (and undownloaded
        (let ((data gnus-newsgroup-data))
          (while (and data
                      (and (not (and undownloaded
-                                    (memq (car data) gnus-newsgroup-undownloaded)))
+                                    (memq (car data)
+                                          gnus-newsgroup-undownloaded)))
                           (if unseen
                               (or (not (memq
                                         (gnus-data-number (car data))
                           (if unseen
                               (or (not (memq
                                         (gnus-data-number (car data))
@@ -9583,7 +9619,7 @@ If NO-EXPIRE, auto-expiry will be inhibited."
        (gnus-summary-goto-unread
         (and gnus-summary-goto-unread
              (not (eq gnus-summary-goto-unread 'never))
        (gnus-summary-goto-unread
         (and gnus-summary-goto-unread
              (not (eq gnus-summary-goto-unread 'never))
-             (not (memq mark (list gnus-unread-mark
+             (not (memq mark (list gnus-unread-mark gnus-spam-mark
                                    gnus-ticked-mark gnus-dormant-mark)))))
        (n (abs n))
        (mark (or mark gnus-del-mark)))
                                    gnus-ticked-mark gnus-dormant-mark)))))
        (n (abs n))
        (mark (or mark gnus-del-mark)))
@@ -10803,7 +10839,8 @@ If REVERSE, save parts that do not match TYPE."
       (set-buffer gnus-article-buffer)
       (let ((handles (or gnus-article-mime-handles
                         (mm-dissect-buffer nil gnus-article-loose-mime)
       (set-buffer gnus-article-buffer)
       (let ((handles (or gnus-article-mime-handles
                         (mm-dissect-buffer nil gnus-article-loose-mime)
-                        (mm-uu-dissect))))
+                        (and gnus-article-emulate-mime
+                             (mm-uu-dissect)))))
        (when handles
          (gnus-summary-save-parts-1 type dir handles reverse)
          (unless gnus-article-mime-handles ;; Don't destroy this case.
        (when handles
          (gnus-summary-save-parts-1 type dir handles reverse)
          (unless gnus-article-mime-handles ;; Don't destroy this case.
index a85fda3..df44c27 100644 (file)
 ;; Product information of this gnus.
 (product-provide 'gnus-vers
   (product-define "T-gnus" nil
 ;; Product information of this gnus.
 (product-provide 'gnus-vers
   (product-define "T-gnus" nil
-                 (list 6 15 10
+                 (list 6 15 11
                        (string-to-number gnus-revision-number))))
 
                        (string-to-number gnus-revision-number))))
 
-(defconst gnus-original-version-number "0.10"
+(defconst gnus-original-version-number "0.11"
   "Version number for this version of Gnus.")
 
 (provide 'running-pterodactyl-gnus-0_73-or-later)
   "Version number for this version of Gnus.")
 
 (provide 'running-pterodactyl-gnus-0_73-or-later)
index 18b8115..db2405d 100644 (file)
@@ -667,7 +667,7 @@ be set in `.emacs' instead."
      ()))
   "Face used for normal interest ancient articles.")
 
      ()))
   "Face used for normal interest ancient articles.")
 
-(defface gnus-summary-high-uncached-face
+(defface gnus-summary-high-undownloaded-face
    '((((class color)
        (background light))
       (:bold t :foreground "cyan4" :bold nil))
    '((((class color)
        (background light))
       (:bold t :foreground "cyan4" :bold nil))
@@ -676,7 +676,7 @@ be set in `.emacs' instead."
      (t (:inverse-video t :bold t)))
   "Face used for high interest uncached articles.")
 
      (t (:inverse-video t :bold t)))
   "Face used for high interest uncached articles.")
 
-(defface gnus-summary-low-uncached-face
+(defface gnus-summary-low-undownloaded-face
    '((((class color)
        (background light))
       (:italic t :foreground "cyan4" :bold nil))
    '((((class color)
        (background light))
       (:italic t :foreground "cyan4" :bold nil))
@@ -685,7 +685,7 @@ be set in `.emacs' instead."
      (t (:inverse-video t :italic t)))
   "Face used for low interest uncached articles.")
 
      (t (:inverse-video t :italic t)))
   "Face used for low interest uncached articles.")
 
-(defface gnus-summary-normal-uncached-face
+(defface gnus-summary-normal-undownloaded-face
    '((((class color)
        (background light))
       (:foreground "cyan4" :bold nil))
    '((((class color)
        (background light))
       (:foreground "cyan4" :bold nil))
@@ -1829,6 +1829,10 @@ When a spam group is entered, all unread articles are marked as spam.")
   "The ifile summary exit spam processor.
 Only applicable to spam groups.")
 
   "The ifile summary exit spam processor.
 Only applicable to spam groups.")
 
+(defvar gnus-group-spam-exit-processor-stat "stat"
+  "The spam-stat summary exit spam processor.
+Only applicable to spam groups.")
+
 (defvar gnus-group-spam-exit-processor-bogofilter "bogofilter"
   "The Bogofilter summary exit spam processor.
 Only applicable to spam groups.")
 (defvar gnus-group-spam-exit-processor-bogofilter "bogofilter"
   "The Bogofilter summary exit spam processor.
 Only applicable to spam groups.")
@@ -1837,6 +1841,14 @@ Only applicable to spam groups.")
   "The Blacklist summary exit spam processor.
 Only applicable to spam groups.")
 
   "The Blacklist summary exit spam processor.
 Only applicable to spam groups.")
 
+(defvar gnus-group-ham-exit-processor-ifile "ifile-ham"
+  "The ifile summary exit ham processor.
+Only applicable to non-spam (unclassified and ham) groups.")
+
+(defvar gnus-group-ham-exit-processor-stat "stat-ham"
+  "The spam-stat summary exit ham processor.
+Only applicable to non-spam (unclassified and ham) groups.")
+
 (defvar gnus-group-ham-exit-processor-whitelist "whitelist"
   "The whitelist summary exit ham processor.
 Only applicable to non-spam (unclassified and ham) groups.")
 (defvar gnus-group-ham-exit-processor-whitelist "whitelist"
   "The whitelist summary exit ham processor.
 Only applicable to non-spam (unclassified and ham) groups.")
@@ -1853,8 +1865,11 @@ Only applicable to non-spam (unclassified and ham) groups.")
                          (list :tag "Spam Summary Exit Processor Choices"
                           (set 
                            (variable-item gnus-group-spam-exit-processor-ifile)
                          (list :tag "Spam Summary Exit Processor Choices"
                           (set 
                            (variable-item gnus-group-spam-exit-processor-ifile)
+                           (variable-item gnus-group-spam-exit-processor-stat)
                            (variable-item gnus-group-spam-exit-processor-bogofilter)
                            (variable-item gnus-group-spam-exit-processor-blacklist)
                            (variable-item gnus-group-spam-exit-processor-bogofilter)
                            (variable-item gnus-group-spam-exit-processor-blacklist)
+                           (variable-item gnus-group-ham-exit-processor-ifile)
+                           (variable-item gnus-group-ham-exit-processor-stat)
                            (variable-item gnus-group-ham-exit-processor-whitelist)
                            (variable-item gnus-group-ham-exit-processor-BBDB))))
  :function-document
                            (variable-item gnus-group-ham-exit-processor-whitelist)
                            (variable-item gnus-group-ham-exit-processor-BBDB))))
  :function-document
@@ -1873,8 +1888,11 @@ for mail groups."
                          (regexp :tag "Group Regexp") 
                          (set :tag "Spam/Ham Summary Exit Processor"
                               (variable-item gnus-group-spam-exit-processor-ifile)
                          (regexp :tag "Group Regexp") 
                          (set :tag "Spam/Ham Summary Exit Processor"
                               (variable-item gnus-group-spam-exit-processor-ifile)
+                              (variable-item gnus-group-spam-exit-processor-stat)
                               (variable-item gnus-group-spam-exit-processor-bogofilter)
                               (variable-item gnus-group-spam-exit-processor-blacklist)
                               (variable-item gnus-group-spam-exit-processor-bogofilter)
                               (variable-item gnus-group-spam-exit-processor-blacklist)
+                              (variable-item gnus-group-ham-exit-processor-ifile)
+                              (variable-item gnus-group-ham-exit-processor-stat)
                               (variable-item gnus-group-ham-exit-processor-whitelist)
                               (variable-item gnus-group-ham-exit-processor-BBDB))))
  :parameter-document
                               (variable-item gnus-group-ham-exit-processor-whitelist)
                               (variable-item gnus-group-ham-exit-processor-BBDB))))
  :parameter-document
@@ -1897,15 +1915,46 @@ to do spam-processed article moving, associated with the destination
 group or `nil' for explicit expiration.  This only makes sense for
 mail groups."
  :variable-group spam
 group or `nil' for explicit expiration.  This only makes sense for
 mail groups."
  :variable-group spam
- :variable-type '(repeat :tag "Spam-processed articles destination" 
-                        (list
-                         (regexp :tag "Group Regexp") 
-                         (choice :tag "Destination for spam-processed articles at summary exit"
-                                 (string :tag "Move to a group")
-                                 (other :tag "Expire" nil))))
+ :variable-type '(repeat 
+                 :tag "Spam-processed articles destination" 
+                 (list
+                  (regexp :tag "Group Regexp") 
+                  (choice 
+                   :tag "Destination for spam-processed articles at summary exit"
+                   (string :tag "Move to a group")
+                   (other :tag "Expire" nil))))
  :parameter-document
  "Where spam-processed articles will go at summary exit.")
 
  :parameter-document
  "Where spam-processed articles will go at summary exit.")
 
+(gnus-define-group-parameter
+ ham-process-destination
+ :parameter-type '(choice 
+                  :tag "Destination for ham articles at summary exit from a spam group"
+                         (string :tag "Move to a group")
+                         (other :tag "Do nothing" nil))
+ :function-document
+ "Where ham articles will go at summary exit from a spam group."
+ :variable gnus-ham-process-destinations
+ :variable-default nil
+ :variable-document
+ "*Groups in which to explicitly send ham articles to
+another group, or do nothing (the default).  If non-nil, this should
+be a list of group name regexps that should match all groups in which
+to do ham article moving, associated with the destination
+group or `nil' for explicit ignoring.  This only makes sense for
+mail groups, and only works in spam groups."
+ :variable-group spam
+ :variable-type '(repeat 
+                 :tag "Ham articles destination" 
+                 (list
+                  (regexp :tag "Group Regexp") 
+                  (choice 
+                   :tag "Destination for ham articles at summary exit from spam group"
+                   (string :tag "Move to a group")
+                   (other :tag "Expire" nil))))
+ :parameter-document
+ "Where ham articles will go at summary exit from a spam group.")
+
 (defcustom gnus-group-uncollapsed-levels 1
   "Number of group name elements to leave alone when making a short group name."
   :group 'gnus-group-visual
 (defcustom gnus-group-uncollapsed-levels 1
   "Number of group name elements to leave alone when making a short group name."
   :group 'gnus-group-visual
@@ -2339,7 +2388,8 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
      ("gnus-demon" :interactive t
       gnus-demon-init gnus-demon-cancel)
      ("gnus-fun" gnus-convert-gray-x-face-to-xpm gnus-display-x-face-in-from
      ("gnus-demon" :interactive t
       gnus-demon-init gnus-demon-cancel)
      ("gnus-fun" gnus-convert-gray-x-face-to-xpm gnus-display-x-face-in-from
-      gnus-convert-image-to-gray-x-face)
+      gnus-convert-image-to-gray-x-face gnus-convert-face-to-png
+      gnus-face-from-file)
      ("gnus-salt" gnus-highlight-selected-tree gnus-possibly-generate-tree
       gnus-tree-open gnus-tree-close gnus-carpal-setup-buffer)
      ("gnus-nocem" gnus-nocem-scan-groups gnus-nocem-close
      ("gnus-salt" gnus-highlight-selected-tree gnus-possibly-generate-tree
       gnus-tree-open gnus-tree-close gnus-carpal-setup-buffer)
      ("gnus-nocem" gnus-nocem-scan-groups gnus-nocem-close
index 81158a7..2e1e2e7 100644 (file)
@@ -9,12 +9,14 @@
 (defun maybe-bind (args)
   (mapcar (lambda (var) (unless (boundp var) (set var nil))) args))
 
 (defun maybe-bind (args)
   (mapcar (lambda (var) (unless (boundp var) (set var nil))) args))
 
-(maybe-fbind '(create-image display-graphic-p
+(maybe-fbind '(bbdb-create-internal bbdb-records
+              create-image display-graphic-p
               display-time-event-handler find-image image-size
               image-type-available-p insert-image
               make-mode-line-mouse-map make-temp-file propertize
               put-image replace-regexp-in-string rmail-msg-is-pruned
               rmail-msg-restore-non-pruned-header sort-coding-systems
               display-time-event-handler find-image image-size
               image-type-available-p insert-image
               make-mode-line-mouse-map make-temp-file propertize
               put-image replace-regexp-in-string rmail-msg-is-pruned
               rmail-msg-restore-non-pruned-header sort-coding-systems
+              spam-BBDB-register-routine spam-enter-ham-BBDB
               tool-bar-add-item tool-bar-add-item-from-menu
               tool-bar-local-item-from-menu url-http-file-exists-p
               vcard-pretty-print w32-focus-frame
               tool-bar-add-item tool-bar-add-item-from-menu
               tool-bar-local-item-from-menu url-http-file-exists-p
               vcard-pretty-print w32-focus-frame
@@ -50,7 +52,7 @@
                    mouse-selection-click-count-buffer pgg-parse-crc24
                    temporary-file-directory transient-mark-mode)))
   (maybe-fbind '(bbdb-complete-name
                    mouse-selection-click-count-buffer pgg-parse-crc24
                    temporary-file-directory transient-mark-mode)))
   (maybe-fbind '(bbdb-complete-name
-                bbdb-records delete-annotation device-connection dfw-device
+                delete-annotation device-connection dfw-device
                 events-to-keys font-lock-set-defaults frame-device
                 glyph-height glyph-width mail-aliases-setup make-annotation
                 make-event make-glyph make-network-process map-extents
                 events-to-keys font-lock-set-defaults frame-device
                 glyph-height glyph-width mail-aliases-setup make-annotation
                 make-event make-glyph make-network-process map-extents
index fd193b5..4ef4770 100644 (file)
@@ -55,6 +55,7 @@
              (list 'const (car a)))
            imap-stream-alist)))
 
              (list 'const (car a)))
            imap-stream-alist)))
 
+;;;###autoload
 (defcustom mail-sources nil
   "*Where the mail backends will look for incoming mail.
 This variable is a list of mail source specifiers.
 (defcustom mail-sources nil
   "*Where the mail backends will look for incoming mail.
 This variable is a list of mail source specifiers.
index c1f99f4..079faca 100644 (file)
@@ -1,5 +1,5 @@
 ;;; message.el --- composing mail and news messages
 ;;; message.el --- composing mail and news messages
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
@@ -269,9 +269,9 @@ If nil, don't insert any text in the body."
 
 ;;;###autoload
 (defcustom message-cross-post-default t
 
 ;;;###autoload
 (defcustom message-cross-post-default t
-  "When non-nil `message-cross-post-followup-to' will normally perform a
-crosspost.  If nil, `message-cross-post-followup-to' will only do a followup.
-Note that you can explicitly override this setting by calling
+  "When non-nil `message-cross-post-followup-to' will perform a crosspost.
+If nil, `message-cross-post-followup-to' will only do a followup.  Note that
+you can explicitly override this setting by calling
 `message-cross-post-followup-to' with a prefix."
   :type 'boolean
   :group 'message-various)
 `message-cross-post-followup-to' with a prefix."
   :type 'boolean
   :group 'message-various)
@@ -296,7 +296,7 @@ Note that you can explicitly override this setting by calling
   "Function to use to insert note about Crosspost or Followup-To.
 The function will be called with four arguments.  The function should not only
 insert a note, but also ensure old notes are deleted.  See the documentation
   "Function to use to insert note about Crosspost or Followup-To.
 The function will be called with four arguments.  The function should not only
 insert a note, but also ensure old notes are deleted.  See the documentation
-for `message-cross-post-insert-note'. "
+for `message-cross-post-insert-note'."
   :type 'function
   :group 'message-various)
 
   :type 'function
   :group 'message-various)
 
@@ -342,7 +342,7 @@ Checks include `subject-cmsg', `multiple-headers', `sendsys',
 `approved', `sender', `empty', `empty-headers', `message-id', `from',
 `subject', `shorten-followup-to', `existing-newsgroups',
 `buffer-file-name', `unchanged', `newsgroups', `reply-to',
 `approved', `sender', `empty', `empty-headers', `message-id', `from',
 `subject', `shorten-followup-to', `existing-newsgroups',
 `buffer-file-name', `unchanged', `newsgroups', `reply-to',
-'continuation-headers'."
+'continuation-headers', and `long-header-lines'."
   :group 'message-news
   :type '(repeat sexp))                        ; Fixme: improve this
 
   :group 'message-news
   :type '(repeat sexp))                        ; Fixme: improve this
 
@@ -846,7 +846,9 @@ Note that the variable `message-deletable-headers' specifies headers which
 are to be deleted and then re-generated before sending, so this variable
 will not have a visible effect for those headers."
   :group 'message-headers
 are to be deleted and then re-generated before sending, so this variable
 will not have a visible effect for those headers."
   :group 'message-headers
-  :type 'boolean)
+  :type '(choice (const :tag "None" nil)
+                 (const :tag "All" t)
+                 (repeat (sexp :tag "Header"))))
 
 (defcustom message-setup-hook '(turn-on-mime-edit)
   "Normal hook, run each time a new outgoing message is initialized.
 
 (defcustom message-setup-hook '(turn-on-mime-edit)
   "Normal hook, run each time a new outgoing message is initialized.
@@ -1164,7 +1166,7 @@ A value of nil means exclude your own user name only."
   "*A list of GNKSA feet you are allowed to shoot.
 Gnus gives you all the opportunity you could possibly want for
 shooting yourself in the foot.  Also, Gnus allows you to shoot the
   "*A list of GNKSA feet you are allowed to shoot.
 Gnus gives you all the opportunity you could possibly want for
 shooting yourself in the foot.  Also, Gnus allows you to shoot the
-feet of Good Net-Keeping Seal of Approval. The following are foot
+feet of Good Net-Keeping Seal of Approval.  The following are foot
 candidates:
 `empty-article'     Allow you to post an empty article;
 `quoted-text-only'  Allow you to post quoted text only;
 candidates:
 `empty-article'     Allow you to post an empty article;
 `quoted-text-only'  Allow you to post quoted text only;
@@ -1753,7 +1755,9 @@ is used by default."
 (defun message-fetch-reply-field (header)
   "Fetch field HEADER from the message we're replying to."
   (message-with-reply-buffer
 (defun message-fetch-reply-field (header)
   "Fetch field HEADER from the message we're replying to."
   (message-with-reply-buffer
-   (message-fetch-field header)))
+    (save-restriction
+      (mail-narrow-to-head)
+      (message-fetch-field header))))
 
 (defun message-set-work-buffer ()
   (if (get-buffer " *message work*")
 
 (defun message-set-work-buffer ()
   (if (get-buffer " *message work*")
@@ -1793,7 +1797,7 @@ is used by default."
 ;;; Start of functions adopted from `message-utils.el'.
 
 (defun message-strip-subject-trailing-was (subject)
 ;;; Start of functions adopted from `message-utils.el'.
 
 (defun message-strip-subject-trailing-was (subject)
-  "Remove trailing \"(Was: <old subject>)\" from subject lines.
+  "Remove trailing \"(Was: <old subject>)\" from SUBJECT lines.
 Leading \"Re: \" is not stripped by this function.  Use the function
 `message-strip-subject-re' for this."
   (let* ((query message-subject-trailing-was-query)
 Leading \"Re: \" is not stripped by this function.  Use the function
 `message-strip-subject-re' for this."
   (let* ((query message-subject-trailing-was-query)
@@ -1828,7 +1832,7 @@ Leading \"Re: \" is not stripped by this function.  Use the function
 
 ;;;###autoload
 (defun message-change-subject (new-subject)
 
 ;;;###autoload
 (defun message-change-subject (new-subject)
-  "Ask for new Subject: header, append (was: <Old Subject>)."
+  "Ask for NEW-SUBJECT header, append (was: <Old Subject>)."
   (interactive
    (list
     (read-from-minibuffer "New subject: ")))
   (interactive
    (list
     (read-from-minibuffer "New subject: ")))
@@ -1838,7 +1842,7 @@ Leading \"Re: \" is not stripped by this function.  Use the function
         (save-excursion
           (let ((old-subject (message-fetch-field "Subject")))
             (cond ((not old-subject)
         (save-excursion
           (let ((old-subject (message-fetch-field "Subject")))
             (cond ((not old-subject)
-                   (error "No current subject."))
+                   (error "No current subject"))
                   ((not (string-match
                          (concat "^[ \t]*"
                                  (regexp-quote new-subject)
                   ((not (string-match
                          (concat "^[ \t]*"
                                  (regexp-quote new-subject)
@@ -1868,7 +1872,7 @@ See `message-mark-insert-begin' and `message-mark-insert-end'."
 
 ;;;###autoload
 (defun message-mark-insert-file (file)
 
 ;;;###autoload
 (defun message-mark-insert-file (file)
-  "Inserts FILE at point, marking it with enclosing tags.
+  "Insert FILE at point, marking it with enclosing tags.
 See `message-mark-insert-begin' and `message-mark-insert-end'."
   (interactive "fFile to insert: ")
     ;; reverse insertion to get correct result.
 See `message-mark-insert-begin' and `message-mark-insert-end'."
   (interactive "fFile to insert: ")
     ;; reverse insertion to get correct result.
@@ -1978,7 +1982,7 @@ been made to before the user asked for a Crosspost."
 
 ;;;###autoload
 (defun message-cross-post-followup-to (target-group)
 
 ;;;###autoload
 (defun message-cross-post-followup-to (target-group)
-  "Crossposts message and sets Followup-To to TARGET-GROUP.
+  "Crossposts message and set Followup-To to TARGET-GROUP.
 With prefix-argument just set Follow-Up, don't cross-post."
   (interactive
    (list ; Completion based on Gnus
 With prefix-argument just set Follow-Up, don't cross-post."
   (interactive
    (list ; Completion based on Gnus
@@ -1998,7 +2002,7 @@ With prefix-argument just set Follow-Up, don't cross-post."
                           (or old-groups ""))))
             ;; check whether target exactly matches old Newsgroups
             (cond ((not old-groups)
                           (or old-groups ""))))
             ;; check whether target exactly matches old Newsgroups
             (cond ((not old-groups)
-                   (error "No current newsgroup."))
+                   (error "No current newsgroup"))
                   ((or (not in-old)
                        (not (string-match
                              (concat "^[ \t]*"
                   ((or (not in-old)
                        (not (string-match
                              (concat "^[ \t]*"
@@ -2226,8 +2230,10 @@ Point is left at the beginning of the narrowed-to region."
   (define-key message-mode-map "\C-c\C-f\C-m" 'message-goto-mail-followup-to)
   (define-key message-mode-map "\C-c\C-f\C-k" 'message-goto-keywords)
   (define-key message-mode-map "\C-c\C-f\C-u" 'message-goto-summary)
   (define-key message-mode-map "\C-c\C-f\C-m" 'message-goto-mail-followup-to)
   (define-key message-mode-map "\C-c\C-f\C-k" 'message-goto-keywords)
   (define-key message-mode-map "\C-c\C-f\C-u" 'message-goto-summary)
-  (define-key message-mode-map "\C-c\C-f\C-i" 'message-insert-or-toggle-importance)
-  (define-key message-mode-map "\C-c\C-f\C-a" 'message-gen-unsubscribed-mft)
+  (define-key message-mode-map "\C-c\C-f\C-i"
+    'message-insert-or-toggle-importance)
+  (define-key message-mode-map "\C-c\C-f\C-a"
+    'message-generate-unsubscribed-mail-followup-to)
 
   ;; modify headers (and insert notes in body)
   (define-key message-mode-map "\C-c\C-fs"    'message-change-subject)
 
   ;; modify headers (and insert notes in body)
   (define-key message-mode-map "\C-c\C-fs"    'message-change-subject)
@@ -2245,12 +2251,13 @@ Point is left at the beginning of the narrowed-to region."
   (define-key message-mode-map "\C-c\C-fc" 'message-goto-mail-copies-to)
 
   (define-key message-mode-map "\C-c\C-t" 'message-insert-to)
   (define-key message-mode-map "\C-c\C-fc" 'message-goto-mail-copies-to)
 
   (define-key message-mode-map "\C-c\C-t" 'message-insert-to)
-  (define-key message-mode-map "\C-c\C-p" 'message-insert-wide-reply)
+  (define-key message-mode-map "\C-c\C-fw" 'message-insert-wide-reply)
   (define-key message-mode-map "\C-c\C-n" 'message-insert-newsgroups)
   (define-key message-mode-map "\C-c\C-l" 'message-to-list-only)
 
   (define-key message-mode-map "\C-c\C-u" 'message-insert-or-toggle-importance)
   (define-key message-mode-map "\C-c\C-n" 'message-insert-newsgroups)
   (define-key message-mode-map "\C-c\C-l" 'message-to-list-only)
 
   (define-key message-mode-map "\C-c\C-u" 'message-insert-or-toggle-importance)
-  (define-key message-mode-map "\C-c\M-n" 'message-insert-disposition-notification-to)
+  (define-key message-mode-map "\C-c\M-n"
+    'message-insert-disposition-notification-to)
 
   (define-key message-mode-map "\C-c\C-y" 'message-yank-original)
   (define-key message-mode-map "\C-c\M-\C-y" 'message-yank-buffer)
 
   (define-key message-mode-map "\C-c\C-y" 'message-yank-original)
   (define-key message-mode-map "\C-c\M-\C-y" 'message-yank-buffer)
@@ -2282,7 +2289,6 @@ Point is left at the beginning of the narrowed-to region."
 (easy-menu-define
  message-mode-menu message-mode-map "Message Menu."
  `("Message"
 (easy-menu-define
  message-mode-menu message-mode-map "Message Menu."
  `("Message"
-   ["Sort Headers" message-sort-headers t]
    ["Yank Original" message-yank-original t]
    ["Fill Yanked Message" message-fill-yanked-message t]
    ["Insert Signature" message-insert-signature t]
    ["Yank Original" message-yank-original t]
    ["Fill Yanked Message" message-fill-yanked-message t]
    ["Insert Signature" message-insert-signature t]
@@ -2293,16 +2299,6 @@ Point is left at the beginning of the narrowed-to region."
    ["Kill To Signature" message-kill-to-signature t]
    ["Newline and Reformat" message-newline-and-reformat t]
    ["Rename buffer" message-rename-buffer t]
    ["Kill To Signature" message-kill-to-signature t]
    ["Newline and Reformat" message-newline-and-reformat t]
    ["Rename buffer" message-rename-buffer t]
-   ["Flag As Important" message-insert-importance-high
-    ,@(if (featurep 'xemacs) '(t)
-       '(:help "Mark this message as important"))]
-   ["Flag As Unimportant" message-insert-importance-low
-    ,@(if (featurep 'xemacs) '(t)
-       '(:help "Mark this message as unimportant"))]
-   ["Request Receipt"
-    message-insert-disposition-notification-to
-    ,@(if (featurep 'xemacs) '(t)
-       '(:help "Request a Disposition Notification of this article"))]
    ["Spellcheck" ispell-message
     ,@(if (featurep 'xemacs) '(t)
        '(:help "Spellcheck this message"))]
    ["Spellcheck" ispell-message
     ,@(if (featurep 'xemacs) '(t)
        '(:help "Spellcheck this message"))]
@@ -2332,7 +2328,7 @@ Point is left at the beginning of the narrowed-to region."
 
 (easy-menu-define
  message-mode-field-menu message-mode-map ""
 
 (easy-menu-define
  message-mode-field-menu message-mode-map ""
- '("Field"
+ `("Field"
    ["Fetch To" message-insert-to t]
    ["Fetch Newsgroups" message-insert-newsgroups t]
    "----"
    ["Fetch To" message-insert-to t]
    ["Fetch Newsgroups" message-insert-newsgroups t]
    "----"
@@ -2344,6 +2340,16 @@ Point is left at the beginning of the narrowed-to region."
    ["Bcc" message-goto-bcc t]
    ["Fcc" message-goto-fcc t]
    ["Reply-To" message-goto-reply-to t]
    ["Bcc" message-goto-bcc t]
    ["Fcc" message-goto-fcc t]
    ["Reply-To" message-goto-reply-to t]
+   ["Flag As Important" message-insert-importance-high
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Mark this message as important"))]
+   ["Flag As Unimportant" message-insert-importance-low
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Mark this message as unimportant"))]
+   ["Request Receipt"
+    message-insert-disposition-notification-to
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Request a receipt notification"))]
    "----"
    ;; (typical) news stuff
    ["Summary" message-goto-summary t]
    "----"
    ;; (typical) news stuff
    ["Summary" message-goto-summary t]
@@ -2362,8 +2368,9 @@ Point is left at the beginning of the narrowed-to region."
    ["Mail-Copies-To" message-goto-mail-copies-to t]
    ["Reduce To: to Cc:" message-reduce-to-to-cc t]
    "----"
    ["Mail-Copies-To" message-goto-mail-copies-to t]
    ["Reduce To: to Cc:" message-reduce-to-to-cc t]
    "----"
-   ["Body" message-goto-body t]
-   ["Signature" message-goto-signature t]))
+   ["Sort Headers" message-sort-headers t]
+   ["Goto Body" message-goto-body t]
+   ["Goto Signature" message-goto-signature t]))
 
 (defvar message-tool-bar-map nil)
 
 
 (defvar message-tool-bar-map nil)
 
@@ -2683,15 +2690,15 @@ return nil."
     (goto-char (point-max))
     nil))
 
     (goto-char (point-max))
     nil))
 
-(defun message-gen-unsubscribed-mft (&optional include-cc)
+(defun message-generate-unsubscribed-mail-followup-to (&optional include-cc)
   "Insert a reasonable MFT header in a post to an unsubscribed list.
 When making original posts to a mailing list you are not subscribed to,
 you have to type in a MFT header by hand.  The contents, usually, are
 the addresses of the list and your own address.  This function inserts
 such a header automatically.  It fetches the contents of the To: header
   "Insert a reasonable MFT header in a post to an unsubscribed list.
 When making original posts to a mailing list you are not subscribed to,
 you have to type in a MFT header by hand.  The contents, usually, are
 the addresses of the list and your own address.  This function inserts
 such a header automatically.  It fetches the contents of the To: header
-in the current mail buffer, and appends the current user-mail-address.
+in the current mail buffer, and appends the current `user-mail-address'.
 
 
-If the optional argument `include-cc' is non-nil, the addresses in the
+If the optional argument INCLUDE-CC is non-nil, the addresses in the
 Cc: header are also put into the MFT."
 
   (interactive "P")
 Cc: header are also put into the MFT."
 
   (interactive "P")
@@ -3886,7 +3893,7 @@ This sub function is for exclusive use of `message-send-mail'."
               (not (mail-fetch-field "mail-followup-to")))
          (setq headers
                (cons
               (not (mail-fetch-field "mail-followup-to")))
          (setq headers
                (cons
-                (cons "Mail-Followup-To" (message-make-mft))
+                (cons "Mail-Followup-To" (message-make-mail-followup-to))
                 message-required-mail-headers))
        ;; otherwise, delete the MFT header if the field is empty
        (when (equal "" (mail-fetch-field "mail-followup-to"))
                 message-required-mail-headers))
        ;; otherwise, delete the MFT header if the field is empty
        (when (equal "" (mail-fetch-field "mail-followup-to"))
@@ -4315,6 +4322,24 @@ Otherwise, generate and save a value for `canlock-password' first."
         (y-or-n-p
          "The control code \"cmsg\" is in the subject.  Really post? ")
        t))
         (y-or-n-p
          "The control code \"cmsg\" is in the subject.  Really post? ")
        t))
+   ;; Check long header lines.
+   (message-check 'long-header-lines
+     (let ((start (point))
+          (header nil)
+          (length 0)
+          found)
+       (while (and (not found)
+                  (re-search-forward "^\\([^ \t:]+\\): " nil t))
+        (if (> (- (point) (match-beginning 0)) 998)
+            (setq found t
+                  length (- (point) (match-beginning 0)))
+          (setq header (match-string-no-properties 1)))
+        (setq start (match-beginning 0))
+        (forward-line 1))
+       (if found
+          (y-or-n-p (format "Your %s header is too long (%d).  Really post? "
+                            header length))
+        t)))
    ;; Check for multiple identical headers.
    (message-check 'multiple-headers
      (let (found)
    ;; Check for multiple identical headers.
    (message-check 'multiple-headers
      (let (found)
@@ -5073,7 +5098,7 @@ give as trustworthy answer as possible."
   "Send a message to the list only.
 Remove all addresses but the list address from To and Cc headers."
   (interactive)
   "Send a message to the list only.
 Remove all addresses but the list address from To and Cc headers."
   (interactive)
-  (let ((listaddr (message-make-mft t)))
+  (let ((listaddr (message-make-mail-followup-to t)))
     (when listaddr
       (save-excursion
        (message-remove-header "to")
     (when listaddr
       (save-excursion
        (message-remove-header "to")
@@ -5081,10 +5106,10 @@ Remove all addresses but the list address from To and Cc headers."
        (message-position-on-field "To" "X-Draft-From")
        (insert listaddr)))))
 
        (message-position-on-field "To" "X-Draft-From")
        (insert listaddr)))))
 
-(defun message-make-mft (&optional only-show-subscribed)
-  "Return the Mail-Followup-To header. If passed the optional
-argument `only-show-subscribed' only return the subscribed address (and
-not the additional To and Cc header contents)."
+(defun message-make-mail-followup-to (&optional only-show-subscribed)
+  "Return the Mail-Followup-To header.
+If passed the optional argument ONLY-SHOW-SUBSCRIBED only return the
+subscribed address (and not the additional To and Cc header contents)."
   (let* ((case-fold-search t)
         (to (message-fetch-field "To"))
         (cc (message-fetch-field "cc"))
   (let* ((case-fold-search t)
         (to (message-fetch-field "To"))
         (cc (message-fetch-field "cc"))
@@ -5175,6 +5200,7 @@ Headers already prepared in the buffer are not modified."
           (User-Agent (message-make-user-agent))
           (Expires (message-make-expires))
           (case-fold-search t)
           (User-Agent (message-make-user-agent))
           (Expires (message-make-expires))
           (case-fold-search t)
+          (optionalp nil)
           header value elem)
       ;; First we remove any old generated headers.
       (let ((headers message-deletable-headers))
           header value elem)
       ;; First we remove any old generated headers.
       (let ((headers message-deletable-headers))
@@ -5196,7 +5222,8 @@ Headers already prepared in the buffer are not modified."
        (setq elem (pop headers))
        (if (consp elem)
            (if (eq (car elem) 'optional)
        (setq elem (pop headers))
        (if (consp elem)
            (if (eq (car elem) 'optional)
-               (setq header (cdr elem))
+               (setq header (cdr elem)
+                     optionalp t)
              (setq header (car elem)))
          (setq header elem))
        (when (or (not (re-search-forward
              (setq header (car elem)))
          (setq header elem))
        (when (or (not (re-search-forward
@@ -5212,7 +5239,7 @@ Headers already prepared in the buffer are not modified."
                    ;; The header was found.  We insert a space after the
                    ;; colon, if there is none.
                    (if (/= (char-after) ? ) (insert " ") (forward-char 1))
                    ;; The header was found.  We insert a space after the
                    ;; colon, if there is none.
                    (if (/= (char-after) ? ) (insert " ") (forward-char 1))
-                   ;; Find out whether the header is empty...
+                   ;; Find out whether the header is empty.
                    (looking-at "[ \t]*\n[^ \t]")))
          ;; So we find out what value we should insert.
          (setq value
                    (looking-at "[ \t]*\n[^ \t]")))
          ;; So we find out what value we should insert.
          (setq value
@@ -5269,9 +5296,12 @@ Headers already prepared in the buffer are not modified."
                ;; The value of this header was empty, so we clear
                ;; totally and insert the new value.
                (delete-region (point) (gnus-point-at-eol))
                ;; The value of this header was empty, so we clear
                ;; totally and insert the new value.
                (delete-region (point) (gnus-point-at-eol))
-               (insert value)
-               (when (bolp)
-                 (delete-char -1)))
+               ;; If the header is optional, and the header was
+               ;; empty, we can't insert it anyway.
+               (unless optionalp
+                 (insert value)
+                 (when (bolp)
+                   (delete-char -1))))
              ;; Add the deletable property to the headers that require it.
              (and (memq header message-deletable-headers)
                   (progn (beginning-of-line) (looking-at "[^:]+: "))
              ;; Add the deletable property to the headers that require it.
              (and (memq header message-deletable-headers)
                   (progn (beginning-of-line) (looking-at "[^:]+: "))
@@ -6707,6 +6737,9 @@ which specify the range to operate on."
 ;;             tool-bar-map mime-edit-mode-map)
               (message-tool-bar-local-item-from-menu
                'ispell-message "spell" tool-bar-map message-mode-map)
 ;;             tool-bar-map mime-edit-mode-map)
               (message-tool-bar-local-item-from-menu
                'ispell-message "spell" tool-bar-map message-mode-map)
+;;            (message-tool-bar-local-item-from-menu
+;;             'mime-edit-preview-message "preview"
+;;             tool-bar-map mime-edit-mode-map)
               (message-tool-bar-local-item-from-menu
                'message-insert-importance-high "important"
                tool-bar-map message-mode-map)
               (message-tool-bar-local-item-from-menu
                'message-insert-importance-high "important"
                tool-bar-map message-mode-map)
index b343351..eef4d16 100644 (file)
@@ -1,5 +1,5 @@
 ;;; mm-decode.el --- Functions for decoding MIME things
 ;;; mm-decode.el --- Functions for decoding MIME things
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>
@@ -178,7 +178,7 @@ consider all the urls to be safe."
      mm-inline-image
      (lambda (handle)
        (mm-valid-and-fit-image-p 'xpm handle)))
      mm-inline-image
      (lambda (handle)
        (mm-valid-and-fit-image-p 'xpm handle)))
-    ("image/x-pixmap"
+    ("image/x-xpixmap"
      mm-inline-image
      (lambda (handle)
        (mm-valid-and-fit-image-p 'xpm handle)))
      mm-inline-image
      (lambda (handle)
        (mm-valid-and-fit-image-p 'xpm handle)))
index 37dfc0c..38dedc2 100644 (file)
@@ -62,7 +62,8 @@
    ((exec-installed-p "lynx") 'lynx)
    ((exec-installed-p "curl") 'curl)
    (t "GET"))
    ((exec-installed-p "lynx") 'lynx)
    ((exec-installed-p "curl") 'curl)
    (t "GET"))
-  "The url grab program."
+  "The url grab program.
+Likely values are `wget', `w3m', `lynx' and `curl'."
   :type '(choice
          (symbol :tag "wget" wget)
          (symbol :tag "w3m" w3m)
   :type '(choice
          (symbol :tag "wget" wget)
          (symbol :tag "w3m" w3m)
index 3f10b6a..94bcabf 100644 (file)
@@ -496,8 +496,8 @@ If the charset is `composition', return the actual one."
              (forward-char))
             (t
              (insert-before-markers (prog1 (+ c (car (cdr item)))
              (forward-char))
             (t
              (insert-before-markers (prog1 (+ c (car (cdr item)))
-                                      (delete-char 1))))
-           (skip-chars-forward "\0-\177"))))
+                                      (delete-char 1)))))
+           (skip-chars-forward "\0-\177")))
        (not inconvertible))))
 
 (defun mm-sort-coding-systems-predicate (a b)
        (not inconvertible))))
 
 (defun mm-sort-coding-systems-predicate (a b)
@@ -535,7 +535,8 @@ charset, and a longer list means no appropriate charset."
               (mapcar 'mm-mime-charset
                       (delq 'ascii
                             (mm-find-charset-region b e))))))
               (mapcar 'mm-mime-charset
                       (delq 'ascii
                             (mm-find-charset-region b e))))))
-    (if (and (memq 'iso-8859-15 charsets)
+    (if (and (> (length charsets) 1)
+            (memq 'iso-8859-15 charsets)
             (memq 'iso-8859-15 hack-charsets)
             (save-excursion (mm-iso-8859-x-to-15-region b e)))
        (mapcar (lambda (x) (setq charsets (delq (car x) charsets)))
             (memq 'iso-8859-15 hack-charsets)
             (save-excursion (mm-iso-8859-x-to-15-region b e)))
        (mapcar (lambda (x) (setq charsets (delq (car x) charsets)))
index 97ed2c7..1018f39 100644 (file)
@@ -1009,15 +1009,15 @@ TYPE is the MIME type to use."
   (mml-insert-tag 'part 'type type 'disposition "inline")
   (forward-line -1))
 
   (mml-insert-tag 'part 'type type 'disposition "inline")
   (forward-line -1))
 
-(defun mml-preview-insert-mft ()
+(defun mml-preview-insert-mail-followup-to ()
   "Insert a Mail-Followup-To header before previewing an article.
 Should be adopted if code in `message-send-mail' is changed."
   (when (and (message-mail-p)
             (message-subscribed-p)
             (not (mail-fetch-field "mail-followup-to"))
   "Insert a Mail-Followup-To header before previewing an article.
 Should be adopted if code in `message-send-mail' is changed."
   (when (and (message-mail-p)
             (message-subscribed-p)
             (not (mail-fetch-field "mail-followup-to"))
-            (message-make-mft))
+            (message-make-mail-followup-to))
     (message-position-on-field "Mail-Followup-To" "X-Draft-From")
     (message-position-on-field "Mail-Followup-To" "X-Draft-From")
-    (insert (message-make-mft))))
+    (insert (message-make-mail-followup-to))))
 
 (defun mml-preview (&optional raw)
   "Display current buffer with Gnus, in a new buffer.
 
 (defun mml-preview (&optional raw)
   "Display current buffer with Gnus, in a new buffer.
@@ -1039,7 +1039,7 @@ If RAW, don't highlight the article."
                                   "*MIME preview of ") (buffer-name))))
       (erase-buffer)
       (insert-buffer buf)
                                   "*MIME preview of ") (buffer-name))))
       (erase-buffer)
       (insert-buffer buf)
-      (mml-preview-insert-mft)
+      (mml-preview-insert-mail-followup-to)
       (let ((message-deletable-headers (if (message-news-p)
                                           nil
                                         message-deletable-headers)))
       (let ((message-deletable-headers (if (message-news-p)
                                           nil
                                         message-deletable-headers)))
@@ -1068,6 +1068,10 @@ If RAW, don't highlight the article."
            (gnus-article-prepare-display))))
       ;; Disable article-mode-map.
       (use-local-map nil)
            (gnus-article-prepare-display))))
       ;; Disable article-mode-map.
       (use-local-map nil)
+      (make-local-hook 'kill-buffer-hook)
+      (add-hook 'kill-buffer-hook
+               (lambda ()
+                 (mm-destroy-parts gnus-article-mime-handles)) nil t)
       (setq buffer-read-only t)
       (local-set-key "q" (lambda () (interactive) (kill-buffer nil)))
       (goto-char (point-min)))))
       (setq buffer-read-only t)
       (local-set-key "q" (lambda () (interactive) (kill-buffer nil)))
       (goto-char (point-min)))))
index 0a0ff24..b0ffdbb 100644 (file)
           dir file)
       (nnheader-re-read-dir pathname)
       (setq dir (mapcar (lambda (name) (string-to-int (substring name 1)))
           dir file)
       (nnheader-re-read-dir pathname)
       (setq dir (mapcar (lambda (name) (string-to-int (substring name 1)))
-                       (directory-files pathname nil "^#[0-9]+#$" t)))
+                       (ignore-errors (directory-files
+                                       pathname nil "^#[0-9]+#$" t))))
       (dolist (n dir)
        (unless (file-exists-p
                 (setq file (expand-file-name (int-to-string n) pathname)))
       (dolist (n dir)
        (unless (file-exists-p
                 (setq file (expand-file-name (int-to-string n) pathname)))
index f36059b..a4456af 100644 (file)
@@ -1504,21 +1504,22 @@ find-file-hooks, etc.
 (defun nnheader-insert-nov-file (file first)
   (let ((size (nth 7 (file-attributes file)))
        (cutoff (* 32 1024)))
 (defun nnheader-insert-nov-file (file first)
   (let ((size (nth 7 (file-attributes file)))
        (cutoff (* 32 1024)))
-    (if (< size cutoff)
-       ;; If the file is small, we just load it.
-       (nnheader-insert-file-contents file)
-      ;; We start on the assumption that FIRST is pretty recent.  If
-      ;; not, we just insert the rest of the file as well.
-      (let (current)
-       (nnheader-insert-file-contents file nil (- size cutoff) size)
-       (goto-char (point-min))
-       (delete-region (point) (or (search-forward "\n" nil 'move) (point)))
-       (setq current (ignore-errors (read (current-buffer))))
-       (if (and (numberp current)
-                (< current first))
-           t
-         (delete-region (point-min) (point-max))
-         (nnheader-insert-file-contents file))))))
+    (when size
+      (if (< size cutoff)
+          ;; If the file is small, we just load it.
+          (nnheader-insert-file-contents file)
+        ;; We start on the assumption that FIRST is pretty recent.  If
+        ;; not, we just insert the rest of the file as well.
+        (let (current)
+          (nnheader-insert-file-contents file nil (- size cutoff) size)
+          (goto-char (point-min))
+          (delete-region (point) (or (search-forward "\n" nil 'move) (point)))
+          (setq current (ignore-errors (read (current-buffer))))
+          (if (and (numberp current)
+                   (< current first))
+              t
+            (delete-region (point-min) (point-max))
+            (nnheader-insert-file-contents file)))))))
 
 (defun nnheader-find-file-noselect (&rest args)
   (let ((format-alist nil)
 
 (defun nnheader-find-file-noselect (&rest args)
   (let ((format-alist nil)
index 1c51c62..bd95e69 100644 (file)
@@ -1749,9 +1749,11 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
     (when (nnheader-functionp target)
       (setq target (funcall target group)))
     (unless (eq target 'delete)
     (when (nnheader-functionp target)
       (setq target (funcall target group)))
     (unless (eq target 'delete)
-      (let ((group-art (gnus-request-accept-article target nil nil t)))
-       (when (consp group-art)
-         (gnus-group-mark-article-read target (cdr group-art)))))))
+      (when (or (gnus-request-group target)
+               (gnus-request-create-group target))
+       (let ((group-art (gnus-request-accept-article target nil nil t)))
+         (when (consp group-art)
+           (gnus-group-mark-article-read target (cdr group-art))))))))
 
 (defun nnmail-fancy-expiry-target (group)
   "Returns a target expiry group determined by `nnmail-fancy-expiry-targets'."
 
 (defun nnmail-fancy-expiry-target (group)
   "Returns a target expiry group determined by `nnmail-fancy-expiry-targets'."
index 641ebcb..66e82ec 100644 (file)
@@ -462,7 +462,7 @@ by nnmaildir-request-article.")
          (setq nlist (cons (cons num article) nlist))
        (setq insert-nlist t
              nlist-cdr (cdr nlist))
          (setq nlist (cons (cons num article) nlist))
        (setq insert-nlist t
              nlist-cdr (cdr nlist))
-       (while (< num (caar nlist-cdr))
+       (while (and nlist-cdr (< num (caar nlist-cdr)))
          (setq nlist nlist-cdr
                nlist-cdr (cdr nlist))))
       (let ((inhibit-quit t))
          (setq nlist nlist-cdr
                nlist-cdr (cdr nlist))))
       (let ((inhibit-quit t))
index a2181cd..00c10bd 100644 (file)
     ("Reuters.Health.rdf"
      "http://www.reutershealth.com/eline.rdf"
      "Consumer-oriented health-related news stories.")
     ("Reuters.Health.rdf"
      "http://www.reutershealth.com/eline.rdf"
      "Consumer-oriented health-related news stories.")
-    ;;("4xt" "http://4xt.org/news/general.rss10" "Resources for XT users.")
     ("Aaronland" "http://aaronland.net/xml/abhb.rdf" "A boy and his basement.")
     ("Art of the Mix" "http://www.artofthemix.org/xml/rss.asp" "A website devoted to the art of making mixed tapes and cds.")
     ("Dave Beckett's RDF Resource Guide" "http://www.ilrt.bristol.ac.uk/discovery/rdf/resources/rss.rdf" "A comprehensive guide to resources about RDF.")
     ("David Chess" "http://www.davidchess.com/words/log.rss" "Mostly-daily musings on philosophy, children, culture, technology, the emergence of life from matter, chocolate, Nomic, and all that sort of thing.")
     ("Aaronland" "http://aaronland.net/xml/abhb.rdf" "A boy and his basement.")
     ("Art of the Mix" "http://www.artofthemix.org/xml/rss.asp" "A website devoted to the art of making mixed tapes and cds.")
     ("Dave Beckett's RDF Resource Guide" "http://www.ilrt.bristol.ac.uk/discovery/rdf/resources/rss.rdf" "A comprehensive guide to resources about RDF.")
     ("David Chess" "http://www.davidchess.com/words/log.rss" "Mostly-daily musings on philosophy, children, culture, technology, the emergence of life from matter, chocolate, Nomic, and all that sort of thing.")
-    ;;("Dublin Core Metadata Intitiative" "http://www.dublincore.org/news.rss" "Latest news from DCMI.")
     ("Figby Articles" "http://www.figby.com/index-rss.php" "A weblog with daily stories about technology, books and publishing, privacy, science, and occasional humor.")
     ("Figby Articles" "http://www.figby.com/index-rss.php" "A weblog with daily stories about technology, books and publishing, privacy, science, and occasional humor.")
-    ;;("Figby News" "http://www.figby.com/news.php" "Categorized RSS feeds from various sources.")
     ("Figby Quickies" "http://www.figby.com/quickies-rss.php" "Quick commented links to other sites from Figby.com.")
     ("Flutterby!" "http://www.flutterby.com/main.rdf" "News and views from Dan Lyke.")
     ("Figby Quickies" "http://www.figby.com/quickies-rss.php" "Quick commented links to other sites from Figby.com.")
     ("Flutterby!" "http://www.flutterby.com/main.rdf" "News and views from Dan Lyke.")
-    ("Groovelog" "http://groovelog.agora.co.uk/groove+log/groovelog.nsf/today.rss.xml" "The open-access groove users' weblog.")
-    ;;("Groovelog.rss10" "http://groovelog.agora.co.uk/groove+log/groovelog.nsf/today.rss10.xml" "The open-access groove users' weblog.")
+    ("Groovelog"
+     "http://groovelog.agora.co.uk/groove+log/groovelog.nsf/today.rss.xml"
+     "The open-access groove users' weblog.")
     ("Hit or Miss" "http://hit-or-miss.org/rss/" "Daily weblog and journal.")
     ("Hit or Miss" "http://hit-or-miss.org/rss/" "Daily weblog and journal.")
-    ;;("Internet.com Feeds" "http://www.webreference.com/services/news/" "News from ")
     ("Larkfarm News" "http://www.larkfarm.com/Larkfarm.rdf" "Mike Gunderloy's web site.")
     ("Latest RFCs" "http://x42.com/rss/rfc.rss")
     ("Linux Today" "http://linuxtoday.com/backend/biglt.rss")
     ("Linux Today.rdf" "http://linuxtoday.com/backend/my-netscape10.rdf")
     ("More Like This WebLog" "http://www.whump.com/moreLikeThis/RSS" "Because the more you know, the more jokes you get.")
     ("Motivational Quotes of the Day" "http://www.quotationspage.com/data/mqotd.rss" "Four motivational quotations each day from the Quotations Page.")
     ("Larkfarm News" "http://www.larkfarm.com/Larkfarm.rdf" "Mike Gunderloy's web site.")
     ("Latest RFCs" "http://x42.com/rss/rfc.rss")
     ("Linux Today" "http://linuxtoday.com/backend/biglt.rss")
     ("Linux Today.rdf" "http://linuxtoday.com/backend/my-netscape10.rdf")
     ("More Like This WebLog" "http://www.whump.com/moreLikeThis/RSS" "Because the more you know, the more jokes you get.")
     ("Motivational Quotes of the Day" "http://www.quotationspage.com/data/mqotd.rss" "Four motivational quotations each day from the Quotations Page.")
-    ;;("My Netscape Network" "http://www.dmoz.org/Netscape/My_Netscape_Network/")
-    ;;("My UserLand" "http://my.userland.com/choose")
     ("Network World Fusion NetFlash" "http://www.nwfusion.com/netflash.rss" "Daily breaking news about networking products, technologies and services.")
     ("Network World Fusion NetFlash" "http://www.nwfusion.com/netflash.rss" "Daily breaking news about networking products, technologies and services.")
-    ;;("News Feeds" "http://newsfeeds.manilasites.com/" "Jeff Barr highlights high quality RSS feeds.")
-    ;;("News Is Free Export" "http://www.newsisfree.com/export.php3")
     ("News Is Free" "http://www.newsisfree.com/news.rdf.php3")
     ("News Is Free" "http://www.newsisfree.com/news.rdf.php3")
-    ;;("News is Free XML Export" "http://www.newsisfree.com/ocs/directory.xml")
     ("O'Reilly Network Articles" "http://www.oreillynet.com/cs/rss/query/q/260?x-ver=1.0")
     ("Quotes of the Day" "http://www.quotationspage.com/data/qotd.rss" "Four humorous quotations each day from the Quotations Page.")
     ("RDF Interest Group" "http://ilrt.org/discovery/rdf-dev/roads/cgi-bin/desire/ig2rss?list=www-rdf-interest" "An experimental channel scraped from the RDF Interest Group mail archives.")
     ("RDF Logic List" "http://ilrt.org/discovery/rdf-dev/roads/cgi-bin/desire/ig2rss?list=www-rdf-logic" "An experimental channel scraped from the RDF Logic mail archives.")
     ("RSS Info" "http://www.blogspace.com/rss/rss10" "News and information on the RSS format")
     ("O'Reilly Network Articles" "http://www.oreillynet.com/cs/rss/query/q/260?x-ver=1.0")
     ("Quotes of the Day" "http://www.quotationspage.com/data/qotd.rss" "Four humorous quotations each day from the Quotations Page.")
     ("RDF Interest Group" "http://ilrt.org/discovery/rdf-dev/roads/cgi-bin/desire/ig2rss?list=www-rdf-interest" "An experimental channel scraped from the RDF Interest Group mail archives.")
     ("RDF Logic List" "http://ilrt.org/discovery/rdf-dev/roads/cgi-bin/desire/ig2rss?list=www-rdf-logic" "An experimental channel scraped from the RDF Logic mail archives.")
     ("RSS Info" "http://www.blogspace.com/rss/rss10" "News and information on the RSS format")
-    ;;("RSS-DEV listing" "http://www.egroups.com/links/rss-dev/Feeds_000966335046/" "A listing of RSS files from the RSS-DEV list.")
-    ("Semantic Web List" "http://ilrt.org/discovery/rdf-dev/roads/cgi-bin/desire/ig2rss?list=semantic-web" "An experimental channel scraped from the W3C's Semantic Web mail archives.")
-    ;;("Sherch!" "http://www.sherch.com/~pldms/cgi-bin/sherch.pl" "Sherlock for the rest of us.")
-    ;;("Street Fusion Archived Financial Webcasts" "http://partners.streetfusion.com/rdf/archive.rdf")
-    ;;("Street Fusion Upcoming Financial Webcasts" "http://partners.streetfusion.com/rdf/live.rdf")
-    ;;("TNL.net newsletter" "http://www.tnl.net/newsletter/channel100.asp" "A newsletter about Internet technology and issues.")
-    ("W3C" "http://www.w3.org/2000/08/w3c-synd/home.rss" "The latest news at the World Wide Web Consortium.")
-    ;;("XML News: RSS Live Content" "http://www.xmlnews.org/RSS/content.html" "A listing of well-known RSS feeds.")
+    ("Semantic Web List"
+     "http://ilrt.org/discovery/rdf-dev/roads/cgi-bin/desire/ig2rss?list=semantic-web"
+     "An experimental channel scraped from the W3C's Semantic Web mail archives.")
+    ("W3C"
+     "http://www.w3.org/2000/08/w3c-synd/home.rss"
+     "The latest news at the World Wide Web Consortium.")
     ("|fr| XMLfr" "http://xmlfr.org/actualites/general.rss10"
      "French speaking portal site dedicated to XML.")
     ("XMLhack" "http://xmlhack.com/rss10.php"
     ("|fr| XMLfr" "http://xmlfr.org/actualites/general.rss10"
      "French speaking portal site dedicated to XML.")
     ("XMLhack" "http://xmlhack.com/rss10.php"
     ("Jabber Software Foundation News"
      "http://www.jabber.org/news/rss.xml"
      "News and announcements from the Jabber Software Foundation.")
     ("Jabber Software Foundation News"
      "http://www.jabber.org/news/rss.xml"
      "News and announcements from the Jabber Software Foundation.")
-    ))
+    ("MacRumors"
+     "http://www.macrumors.com/macrumors.xml"
+     "The mac news you care about.")
+    ("Mac OS X Hints"
+     "http://www.macosxhints.com/backend/geeklog.rdf"
+     "Mac OS X Hits.")
+    )
+  "List of RSS addresses.")
 
 (defvar nnrss-use-local nil)
 
 
 (defvar nnrss-use-local nil)
 
index 8af722a..fb329d8 100644 (file)
@@ -294,7 +294,9 @@ noticing asynchronous data.")
        nntp-last-command string)
   (when nntp-record-commands
     (nntp-record-command string))
        nntp-last-command string)
   (when nntp-record-commands
     (nntp-record-command string))
-  (process-send-string process (concat string nntp-end-of-line)))
+  (process-send-string process (concat string nntp-end-of-line))
+  (or (memq (process-status process) '(open run))
+      (nntp-report "Server closed connection")))
 
 (defun nntp-record-command (string)
   "Record the command STRING."
 
 (defun nntp-record-command (string)
   "Record the command STRING."
@@ -306,6 +308,27 @@ noticing asynchronous data.")
              "." (format "%03d" (/ (nth 2 time) 1000))
              " " nntp-address " " string "\n"))))
 
              "." (format "%03d" (/ (nth 2 time) 1000))
              " " nntp-address " " string "\n"))))
 
+(defun nntp-report (&rest args)
+  "Report an error from the nntp backend.  The first string in ARGS
+can be a format string.  For some commands, the failed command may be
+retried once before actually displaying the error report."
+
+  (when nntp-record-commands
+    (nntp-record-command "*** CALLED nntp-report ***"))
+
+  (nnheader-report 'nntp args)
+
+  (apply 'error args))
+
+(defun nntp-report-1 (&rest args)
+  "Throws out to nntp-with-open-group-error so that the connection may
+be restored and the command retried."
+
+  (when nntp-record-commands
+    (nntp-record-command "*** CONNECTION LOST ***"))
+
+  (throw 'nntp-with-open-group-error t))
+
 (defsubst nntp-wait-for (process wait-for buffer &optional decode discard)
   "Wait for WAIT-FOR to arrive from PROCESS."
   (save-excursion
 (defsubst nntp-wait-for (process wait-for buffer &optional decode discard)
   "Wait for WAIT-FOR to arrive from PROCESS."
   (save-excursion
@@ -391,32 +414,33 @@ noticing asynchronous data.")
   "Use COMMAND to retrieve data into BUFFER from PORT on ADDRESS."
   (let ((process (or (nntp-find-connection buffer)
                     (nntp-open-connection buffer))))
   "Use COMMAND to retrieve data into BUFFER from PORT on ADDRESS."
   (let ((process (or (nntp-find-connection buffer)
                     (nntp-open-connection buffer))))
-    (if (not process)
-       (nnheader-report 'nntp "Couldn't open connection to %s" address)
-      (unless (or nntp-inhibit-erase nnheader-callback-function)
-       (save-excursion
-         (set-buffer (process-buffer process))
-         (erase-buffer)))
-      (condition-case err
-         (progn
-           (when command
-             (nntp-send-string process command))
-           (cond
-            ((eq callback 'ignore)
-             t)
-            ((and callback wait-for)
-             (nntp-async-wait process wait-for buffer decode callback)
-             t)
-            (wait-for
-             (nntp-wait-for process wait-for buffer decode))
-            (t t)))
-       (error
-        (nnheader-report 'nntp "Couldn't open connection to %s: %s"
-                         address err))
-       (quit
-        (message "Quit retrieving data from nntp")
-        (signal 'quit nil)
-        nil)))))
+    (if process
+        (progn
+          (unless (or nntp-inhibit-erase nnheader-callback-function)
+            (save-excursion
+              (set-buffer (process-buffer process))
+              (erase-buffer)))
+          (condition-case err
+              (progn
+                (when command
+                  (nntp-send-string process command))
+                (cond
+                 ((eq callback 'ignore)
+                  t)
+                 ((and callback wait-for)
+                  (nntp-async-wait process wait-for buffer decode callback)
+                  t)
+                 (wait-for
+                  (nntp-wait-for process wait-for buffer decode))
+                 (t t)))
+            (error
+             (nnheader-report 'nntp "Couldn't open connection to %s: %s"
+                              address err))
+            (quit
+             (message "Quit retrieving data from nntp")
+             (signal 'quit nil)
+             nil)))
+      (nnheader-report 'nntp "Couldn't open connection to %s" address))))
 
 (defsubst nntp-send-command (wait-for &rest strings)
   "Send STRINGS to server and wait until WAIT-FOR returns."
 
 (defsubst nntp-send-command (wait-for &rest strings)
   "Send STRINGS to server and wait until WAIT-FOR returns."
@@ -552,214 +576,227 @@ noticing asynchronous data.")
    (t
     nil)))
 
    (t
     nil)))
 
-(defvar nntp-with-open-group-first-pass nil)
+(eval-when-compile
+  (defvar nntp-with-open-group-internal nil)
+  (defvar nntp-report-n nil))
 
 (defmacro nntp-with-open-group (group server &optional connectionless &rest forms)
 
 (defmacro nntp-with-open-group (group server &optional connectionless &rest forms)
-  "Protect against servers that don't like clients that keep idle connections opens.  The problem
-being that these servers may either close a connection or simply ignore any further requests on a
-connection.  Closed connections are not detected until accept-process-output has updated the
-process-status.  Dropped connections are not detected until the connection timeouts (which may be
-several minutes) or nntp-connection-timeout has expired.  When these occur nntp-with-open-group,
-opens a new connection then re-issues the NNTP command whose response triggered the error."
+  "Protect against servers that don't like clients that keep idle connections opens.
+The problem being that these servers may either close a connection or
+simply ignore any further requests on a connection.  Closed
+connections are not detected until accept-process-output has updated
+the process-status.  Dropped connections are not detected until the
+connection timeouts (which may be several minutes) or
+nntp-connection-timeout has expired.  When these occur
+nntp-with-open-group, opens a new connection then re-issues the NNTP
+command whose response triggered the error."
   (when (and (listp connectionless)
   (when (and (listp connectionless)
-             (not (eq connectionless nil)))
+            (not (eq connectionless nil)))
     (setq forms (cons connectionless forms)
     (setq forms (cons connectionless forms)
-          connectionless nil))
-  `(let ((nntp-with-open-group-first-pass t)
-         nntp-with-open-group-internal)
+         connectionless nil))
+  `(letf ((nntp-report-n (symbol-function 'nntp-report))
+         ((symbol-function 'nntp-report) (symbol-function 'nntp-report-1))
+         (nntp-with-open-group-internal nil))
      (while (catch 'nntp-with-open-group-error
      (while (catch 'nntp-with-open-group-error
-              ;; Open the connection to the server
-              ;; NOTE: Existing connections are NOT tested.
-              (nntp-possibly-change-group ,group ,server ,connectionless)
-              
-              (let ((timer
-                     (and nntp-connection-timeout
-                          (nnheader-run-at-time
-                           nntp-connection-timeout nil
-                           '(lambda ()
-                              (let ((process (nntp-find-connection nntp-server-buffer))
-                                    (buffer  (and process (process-buffer process))))
-                                        ; when I an able to identify the connection to the server AND I've received NO 
-                                        ; reponse for nntp-connection-timeout seconds.
-                                (when (and buffer (eq 0 (buffer-size buffer)))
-                                        ; Close the connection.  Take no other action as the accept input code will
-                                        ; handle the closed connection.
-                                  (nntp-kill-buffer buffer))))))))
-                (unwind-protect
-                    (setq nntp-with-open-group-internal (progn ,@forms))
-                  (when timer
-                    (nnheader-cancel-timer timer)))
-                nil))
-       (setq nntp-with-open-group-first-pass nil))
+             ;; Open the connection to the server
+             ;; NOTE: Existing connections are NOT tested.
+             (nntp-possibly-change-group ,group ,server ,connectionless)
+
+             (let ((timer
+                    (and nntp-connection-timeout
+                         (nnheader-run-at-time
+                          nntp-connection-timeout nil
+                          '(lambda ()
+                             (let ((process (nntp-find-connection
+                                             nntp-server-buffer))
+                                   (buffer  (and process
+                                                 (process-buffer process))))
+                                       ; when I an able to identify
+                                       ; the connection to the server
+                                       ; AND I've received NO reponse
+                                       ; for nntp-connection-timeout
+                                       ; seconds.
+                               (when (and buffer (eq 0 (buffer-size buffer)))
+                                       ; Close the connection.  Take
+                                       ; no other action as the
+                                       ; accept input code will
+                                       ; handle the closed
+                                       ; connection.
+                                 (nntp-kill-buffer buffer))))))))
+               (unwind-protect
+                   (setq nntp-with-open-group-internal
+                          (condition-case nil
+                             (progn ,@forms)
+                           (quit
+                            (nntp-close-server)
+                             (signal 'quit nil)))
+                          )
+                 (when timer
+                   (nnheader-cancel-timer timer)))
+               nil))
+       (setf (symbol-function 'nntp-report) nntp-report-n))
      nntp-with-open-group-internal))
 
      nntp-with-open-group-internal))
 
-(defsubst nntp-report (&rest args)
-  "Report an error from the nntp backend.
-The first string in ARGS can be a format string.
-For some commands, the failed command may be retried once before actually displaying the error report."
-
-  (if nntp-with-open-group-first-pass
-      (throw 'nntp-with-open-group-error t))
-
-  (nnheader-report 'nntp args)
-  )
-
 (deffoo nntp-retrieve-headers (articles &optional group server fetch-old)
   "Retrieve the headers of ARTICLES."
   (nntp-with-open-group
 (deffoo nntp-retrieve-headers (articles &optional group server fetch-old)
   "Retrieve the headers of ARTICLES."
   (nntp-with-open-group
-    group server
-    (save-excursion
-      (set-buffer (nntp-find-connection-buffer nntp-server-buffer))
-      (erase-buffer)
-      (if (and (not gnus-nov-is-evil)
-               (not nntp-nov-is-evil)
-               (nntp-retrieve-headers-with-xover articles fetch-old))
-          ;; We successfully retrieved the headers via XOVER.
-          'nov
-        ;; XOVER didn't work, so we do it the hard, slow and inefficient
-        ;; way.
-        (let ((number (length articles))
-              (count 0)
-              (received 0)
-              (last-point (point-min))
-              (buf (nntp-find-connection-buffer nntp-server-buffer))
-              (nntp-inhibit-erase t)
-              article)
-          ;; Send HEAD commands.
-          (while (setq article (pop articles))
-            (nntp-send-command
-             nil
-             "HEAD" (if (numberp article)
-                        (int-to-string article)
-                      ;; `articles' is either a list of article numbers
-                      ;; or a list of article IDs.
-                      article))
-            (incf count)
-            ;; Every 400 requests we have to read the stream in
-            ;; order to avoid deadlocks.
-            (when (or (null articles)   ;All requests have been sent.
-                      (zerop (% count nntp-maximum-request)))
-              (nntp-accept-response)
-              (while (progn
-                       (set-buffer buf)
-                       (goto-char last-point)
-                       ;; Count replies.
-                       (while (nntp-next-result-arrived-p)
-                         (setq last-point (point))
-                         (incf received))
-                       (< received count))
-                ;; If number of headers is greater than 100, give
-                ;;  informative messages.
-                (and (numberp nntp-large-newsgroup)
-                     (> number nntp-large-newsgroup)
-                     (zerop (% received 20))
-                     (nnheader-message 6 "NNTP: Receiving headers... %d%%"
-                                       (/ (* received 100) number)))
-                (nntp-accept-response))))
-          (and (numberp nntp-large-newsgroup)
-               (> number nntp-large-newsgroup)
-               (nnheader-message 6 "NNTP: Receiving headers...done"))
-
-          ;; Now all of replies are received.  Fold continuation lines.
-          (nnheader-fold-continuation-lines)
-          ;; Remove all "\r"'s.
-          (nnheader-strip-cr)
-          (copy-to-buffer nntp-server-buffer (point-min) (point-max))
-          'headers)))))
+   group server
+   (save-excursion
+     (set-buffer (nntp-find-connection-buffer nntp-server-buffer))
+     (erase-buffer)
+     (if (and (not gnus-nov-is-evil)
+              (not nntp-nov-is-evil)
+              (nntp-retrieve-headers-with-xover articles fetch-old))
+         ;; We successfully retrieved the headers via XOVER.
+         'nov
+       ;; XOVER didn't work, so we do it the hard, slow and inefficient
+       ;; way.
+       (let ((number (length articles))
+             (articles articles)
+             (count 0)
+             (received 0)
+             (last-point (point-min))
+             (buf (nntp-find-connection-buffer nntp-server-buffer))
+             (nntp-inhibit-erase t)
+             article)
+         ;; Send HEAD commands.
+         (while (setq article (pop articles))
+           (nntp-send-command
+            nil
+            "HEAD" (if (numberp article)
+                       (int-to-string article)
+                     ;; `articles' is either a list of article numbers
+                     ;; or a list of article IDs.
+                     article))
+           (incf count)
+           ;; Every 400 requests we have to read the stream in
+           ;; order to avoid deadlocks.
+           (when (or (null articles)    ;All requests have been sent.
+                     (zerop (% count nntp-maximum-request)))
+             (nntp-accept-response)
+             (while (progn
+                      (set-buffer buf)
+                      (goto-char last-point)
+                      ;; Count replies.
+                      (while (nntp-next-result-arrived-p)
+                        (setq last-point (point))
+                        (incf received))
+                      (< received count))
+               ;; If number of headers is greater than 100, give
+               ;;  informative messages.
+               (and (numberp nntp-large-newsgroup)
+                    (> number nntp-large-newsgroup)
+                    (zerop (% received 20))
+                    (nnheader-message 6 "NNTP: Receiving headers... %d%%"
+                                      (/ (* received 100) number)))
+               (nntp-accept-response))))
+         (and (numberp nntp-large-newsgroup)
+              (> number nntp-large-newsgroup)
+              (nnheader-message 6 "NNTP: Receiving headers...done"))
+
+         ;; Now all of replies are received.  Fold continuation lines.
+         (nnheader-fold-continuation-lines)
+         ;; Remove all "\r"'s.
+         (nnheader-strip-cr)
+         (copy-to-buffer nntp-server-buffer (point-min) (point-max))
+         'headers)))))
 
 (deffoo nntp-retrieve-groups (groups &optional server)
   "Retrieve group info on GROUPS."
 
 (deffoo nntp-retrieve-groups (groups &optional server)
   "Retrieve group info on GROUPS."
-  (nntp-possibly-change-group nil server)
-  (when (nntp-find-connection-buffer nntp-server-buffer)
-    (catch 'done
-      (save-excursion
-       ;; Erase nntp-server-buffer before nntp-inhibit-erase.
-       (set-buffer nntp-server-buffer)
-       (erase-buffer)
-       (set-buffer (nntp-find-connection-buffer nntp-server-buffer))
-       ;; The first time this is run, this variable is `try'.  So we
-       ;; try.
-       (when (eq nntp-server-list-active-group 'try)
-         (nntp-try-list-active (car groups)))
-       (erase-buffer)
-       (let ((count 0)
-             (received 0)
-             (last-point (point-min))
-             (nntp-inhibit-erase t)
-             (buf (nntp-find-connection-buffer nntp-server-buffer))
-             (command (if nntp-server-list-active-group
-                          "LIST ACTIVE" "GROUP")))
-         (while groups
-           ;; Timeout may have killed the buffer.
-           (unless (gnus-buffer-live-p buf)
-             (nnheader-report 'nntp "Connection to %s is closed." server)
-             (throw 'done nil))
-           ;; Send the command to the server.
-           (nntp-send-command nil command (pop groups))
-           (incf count)
-           ;; Every 400 requests we have to read the stream in
-           ;; order to avoid deadlocks.
-           (when (or (null groups)     ;All requests have been sent.
-                     (zerop (% count nntp-maximum-request)))
-             (nntp-accept-response)
-             (while (and (gnus-buffer-live-p buf)
-                         (progn
-                           ;; Search `blue moon' in this file for the
-                           ;; reason why set-buffer here.
-                           (set-buffer buf)
-                           (goto-char last-point)
-                           ;; Count replies.
-                           (while (re-search-forward "^[0-9]" nil t)
-                             (incf received))
-                           (setq last-point (point))
-                           (< received count)))
-               (nntp-accept-response))))
-
-         ;; Wait for the reply from the final command.
-         (unless (gnus-buffer-live-p buf)
-           (nnheader-report 'nntp "Connection to %s is closed." server)
-           (throw 'done nil))
-         (set-buffer buf)
-         (goto-char (point-max))
-         (re-search-backward "^[0-9]" nil t)
-         (when (looking-at "^[23]")
-           (while (and (gnus-buffer-live-p buf)
-                       (progn
-                         (set-buffer buf)
-                         (goto-char (point-max))
-                         (if (not nntp-server-list-active-group)
-                             (not (re-search-backward "\r?\n" (- (point) 3) t))
-                           (not (re-search-backward "^\\.\r?\n"
-                                                    (- (point) 4) t)))))
-             (nntp-accept-response)))
-
-         ;; Now all replies are received.  We remove CRs.
-         (unless (gnus-buffer-live-p buf)
-           (nnheader-report 'nntp "Connection to %s is closed." server)
-           (throw 'done nil))
-         (set-buffer buf)
-         (goto-char (point-min))
-         (while (search-forward "\r" nil t)
-           (replace-match "" t t))
-
-         (if (not nntp-server-list-active-group)
-             (progn
-               (copy-to-buffer nntp-server-buffer (point-min) (point-max))
-               'group)
-           ;; We have read active entries, so we just delete the
-           ;; superfluous gunk.
-           (goto-char (point-min))
-           (while (re-search-forward "^[.2-5]" nil t)
-             (delete-region (match-beginning 0)
-                            (progn (forward-line 1) (point))))
-           (copy-to-buffer nntp-server-buffer (point-min) (point-max))
-           'active))))))
+  (nntp-with-open-group
+   nil server
+   (when (nntp-find-connection-buffer nntp-server-buffer)
+     (catch 'done
+       (save-excursion
+         ;; Erase nntp-server-buffer before nntp-inhibit-erase.
+         (set-buffer nntp-server-buffer)
+         (erase-buffer)
+         (set-buffer (nntp-find-connection-buffer nntp-server-buffer))
+         ;; The first time this is run, this variable is `try'.  So we
+         ;; try.
+         (when (eq nntp-server-list-active-group 'try)
+           (nntp-try-list-active (car groups)))
+         (erase-buffer)
+         (let ((count 0)
+               (groups groups)
+               (received 0)
+               (last-point (point-min))
+               (nntp-inhibit-erase t)
+               (buf (nntp-find-connection-buffer nntp-server-buffer))
+               (command (if nntp-server-list-active-group
+                            "LIST ACTIVE" "GROUP")))
+           (while groups
+             ;; Timeout may have killed the buffer.
+             (unless (gnus-buffer-live-p buf)
+               (nnheader-report 'nntp "Connection to %s is closed." server)
+               (throw 'done nil))
+             ;; Send the command to the server.
+             (nntp-send-command nil command (pop groups))
+             (incf count)
+             ;; Every 400 requests we have to read the stream in
+             ;; order to avoid deadlocks.
+             (when (or (null groups)    ;All requests have been sent.
+                       (zerop (% count nntp-maximum-request)))
+               (nntp-accept-response)
+               (while (and (gnus-buffer-live-p buf)
+                           (progn
+                             ;; Search `blue moon' in this file for the
+                             ;; reason why set-buffer here.
+                             (set-buffer buf)
+                             (goto-char last-point)
+                             ;; Count replies.
+                             (while (re-search-forward "^[0-9]" nil t)
+                               (incf received))
+                             (setq last-point (point))
+                             (< received count)))
+                 (nntp-accept-response))))
+
+           ;; Wait for the reply from the final command.
+           (unless (gnus-buffer-live-p buf)
+             (nnheader-report 'nntp "Connection to %s is closed." server)
+             (throw 'done nil))
+           (set-buffer buf)
+           (goto-char (point-max))
+           (re-search-backward "^[0-9]" nil t)
+           (when (looking-at "^[23]")
+             (while (and (gnus-buffer-live-p buf)
+                         (progn
+                           (set-buffer buf)
+                           (goto-char (point-max))
+                           (if (not nntp-server-list-active-group)
+                               (not (re-search-backward "\r?\n" (- (point) 3) t))
+                             (not (re-search-backward "^\\.\r?\n"
+                                                      (- (point) 4) t)))))
+               (nntp-accept-response)))
+
+           ;; Now all replies are received.  We remove CRs.
+           (unless (gnus-buffer-live-p buf)
+             (nnheader-report 'nntp "Connection to %s is closed." server)
+             (throw 'done nil))
+           (set-buffer buf)
+           (goto-char (point-min))
+           (while (search-forward "\r" nil t)
+             (replace-match "" t t))
+
+           (if (not nntp-server-list-active-group)
+               (progn
+                 (copy-to-buffer nntp-server-buffer (point-min) (point-max))
+                 'group)
+             ;; We have read active entries, so we just delete the
+             ;; superfluous gunk.
+             (goto-char (point-min))
+             (while (re-search-forward "^[.2-5]" nil t)
+               (delete-region (match-beginning 0)
+                              (progn (forward-line 1) (point))))
+             (copy-to-buffer nntp-server-buffer (point-min) (point-max))
+             'active)))))))
 
 (deffoo nntp-retrieve-articles (articles &optional group server)
 
 (deffoo nntp-retrieve-articles (articles &optional group server)
-  (nntp-with-open-group 
+  (nntp-with-open-group
     group server
    (save-excursion
      (let ((number (length articles))
     group server
    (save-excursion
      (let ((number (length articles))
+           (articles articles)
            (count 0)
            (received 0)
            (last-point (point-min))
            (count 0)
            (received 0)
            (last-point (point-min))
@@ -837,16 +874,18 @@ For some commands, the failed command may be retried once before actually displa
 
 (deffoo nntp-list-active-group (group &optional server)
   "Return the active info on GROUP (which can be a regexp)."
 
 (deffoo nntp-list-active-group (group &optional server)
   "Return the active info on GROUP (which can be a regexp)."
-  (nntp-possibly-change-group nil server)
-  (nntp-send-command "^\\.*\r?\n" "LIST ACTIVE" group))
+  (nntp-with-open-group
+   nil server
+   (nntp-send-command "^\\.*\r?\n" "LIST ACTIVE" group)))
 
 (deffoo nntp-request-group-articles (group &optional server)
   "Return the list of existing articles in GROUP."
 
 (deffoo nntp-request-group-articles (group &optional server)
   "Return the list of existing articles in GROUP."
-  (nntp-possibly-change-group nil server)
-  (nntp-send-command "^\\.*\r?\n" "LISTGROUP" group))
+  (nntp-with-open-group
+   nil server
+   (nntp-send-command "^\\.*\r?\n" "LISTGROUP" group)))
 
 (deffoo nntp-request-article (article &optional group server buffer command)
 
 (deffoo nntp-request-article (article &optional group server buffer command)
-  (nntp-with-open-group 
+  (nntp-with-open-group
     group server
     (when (nntp-send-command-and-decode
            "\r?\n\\.\r?\n" "ARTICLE"
     group server
     (when (nntp-send-command-and-decode
            "\r?\n\\.\r?\n" "ARTICLE"
@@ -860,19 +899,21 @@ For some commands, the failed command may be retried once before actually displa
         (nntp-find-group-and-number group)))))
 
 (deffoo nntp-request-head (article &optional group server)
         (nntp-find-group-and-number group)))))
 
 (deffoo nntp-request-head (article &optional group server)
-  (nntp-possibly-change-group group server)
-  (when (nntp-send-command
-        "\r?\n\\.\r?\n" "HEAD"
-        (if (numberp article) (int-to-string article) article))
-    (prog1
-       (nntp-find-group-and-number group)
-      (nntp-decode-text))))
+  (nntp-with-open-group
+   group server
+   (when (nntp-send-command
+          "\r?\n\\.\r?\n" "HEAD"
+          (if (numberp article) (int-to-string article) article))
+     (prog1
+         (nntp-find-group-and-number group)
+       (nntp-decode-text)))))
 
 (deffoo nntp-request-body (article &optional group server)
 
 (deffoo nntp-request-body (article &optional group server)
-  (nntp-possibly-change-group group server)
-  (nntp-send-command-and-decode
-   "\r?\n\\.\r?\n" "BODY"
-   (if (numberp article) (int-to-string article) article)))
+  (nntp-with-open-group
+   group server
+   (nntp-send-command-and-decode
+    "\r?\n\\.\r?\n" "BODY"
+    (if (numberp article) (int-to-string article) article))))
 
 (deffoo nntp-request-group (group &optional server dont-check)
   (nntp-with-open-group 
 
 (deffoo nntp-request-group (group &optional server dont-check)
   (nntp-with-open-group 
@@ -942,81 +983,85 @@ output from the server will be restricted to the specified newsgroups.
 If `nntp-options-subscribe' is non-nil, remove newsgroups that do not
 match the regexp.  If `nntp-options-not-subscribe' is non-nil, remove
 newsgroups that match the regexp."
 If `nntp-options-subscribe' is non-nil, remove newsgroups that do not
 match the regexp.  If `nntp-options-not-subscribe' is non-nil, remove
 newsgroups that match the regexp."
-  (nntp-possibly-change-group nil server)
-  (with-current-buffer nntp-server-buffer
-    (prog1
-       (if (not nntp-list-options)
-           (nntp-send-command-and-decode "\r?\n\\.\r?\n" "LIST")
-         (let ((options (if (consp nntp-list-options)
-                            nntp-list-options
-                          (list nntp-list-options)))
-               (ret t))
-           (erase-buffer)
-           (while options
-             (goto-char (point-max))
-             (narrow-to-region (point) (point))
-             (setq ret (and ret
-                            (nntp-send-command-nodelete
-                             "\r?\n\\.\r?\n"
-                             (format "LIST ACTIVE %s" (car options))))
-                   options (cdr options))
-             (nntp-decode-text))
-           (widen)
-           ret))
-      (when (and (stringp nntp-options-subscribe)
-                (not (string-equal "" nntp-options-subscribe)))
-       (goto-char (point-min))
-       (keep-lines nntp-options-subscribe))
-      (when (and (stringp nntp-options-not-subscribe)
-                (not (string-equal "" nntp-options-not-subscribe)))
-       (goto-char (point-min))
-       (flush-lines nntp-options-subscribe)))))
+  (nntp-with-open-group
+   nil server
+   (with-current-buffer nntp-server-buffer
+     (prog1
+        (if (not nntp-list-options)
+            (nntp-send-command-and-decode "\r?\n\\.\r?\n" "LIST")
+          (let ((options (if (consp nntp-list-options)
+                             nntp-list-options
+                           (list nntp-list-options)))
+                (ret t))
+            (erase-buffer)
+            (while options
+              (goto-char (point-max))
+              (narrow-to-region (point) (point))
+              (setq ret (and ret
+                             (nntp-send-command-nodelete
+                              "\r?\n\\.\r?\n"
+                              (format "LIST ACTIVE %s" (car options))))
+                    options (cdr options))
+              (nntp-decode-text))
+            (widen)
+            ret))
+       (when (and (stringp nntp-options-subscribe)
+                 (not (string-equal "" nntp-options-subscribe)))
+        (goto-char (point-min))
+        (keep-lines nntp-options-subscribe))
+       (when (and (stringp nntp-options-not-subscribe)
+                 (not (string-equal "" nntp-options-not-subscribe)))
+        (goto-char (point-min))
+        (flush-lines nntp-options-subscribe))))))
 
 (deffoo nntp-request-list-newsgroups (&optional server)
 
 (deffoo nntp-request-list-newsgroups (&optional server)
-  (nntp-possibly-change-group nil server)
-  (nntp-send-command "\r?\n\\.\r?\n" "LIST NEWSGROUPS"))
+  (nntp-with-open-group
+   nil server
+   (nntp-send-command "\r?\n\\.\r?\n" "LIST NEWSGROUPS")))
 
 (deffoo nntp-request-newgroups (date &optional server)
 
 (deffoo nntp-request-newgroups (date &optional server)
-  (nntp-possibly-change-group nil server)
-  (save-excursion
-    (set-buffer nntp-server-buffer)
-    (let* ((time (date-to-time date))
-          (ls (- (cadr time) (nth 8 (decode-time time)))))
-      (cond ((< ls 0)
-            (setcar time (1- (car time)))
-            (setcar (cdr time) (+ ls 65536)))
-           ((>= ls 65536)
-            (setcar time (1+ (car time)))
-            (setcar (cdr time) (- ls 65536)))
-           (t
-            (setcar (cdr time) ls)))
-      (prog1
-         (nntp-send-command
-          "^\\.\r?\n" "NEWGROUPS"
-          (format-time-string "%y%m%d %H%M%S" time)
-          "GMT")
-       (nntp-decode-text)))))
+  (nntp-with-open-group
+   nil server
+   (save-excursion
+     (set-buffer nntp-server-buffer)
+     (let* ((time (date-to-time date))
+           (ls (- (cadr time) (nth 8 (decode-time time)))))
+       (cond ((< ls 0)
+             (setcar time (1- (car time)))
+             (setcar (cdr time) (+ ls 65536)))
+            ((>= ls 65536)
+             (setcar time (1+ (car time)))
+             (setcar (cdr time) (- ls 65536)))
+            (t
+             (setcar (cdr time) ls)))
+       (prog1
+          (nntp-send-command
+           "^\\.\r?\n" "NEWGROUPS"
+           (format-time-string "%y%m%d %H%M%S" time)
+           "GMT")
+        (nntp-decode-text))))))
 
 (deffoo nntp-request-post (&optional server)
 
 (deffoo nntp-request-post (&optional server)
-  (nntp-possibly-change-group nil server)
-  (when (nntp-send-command "^[23].*\r?\n" "POST")
-    (let ((response (with-current-buffer nntp-server-buffer
-                     nntp-process-response))
-         server-id)
-      (when (and response
-                (string-match "^[23].*\\(<[^\t\n @<>]+@[^\t\n @<>]+>\\)"
-                              response))
-       (setq server-id (match-string 1 response))
-       (narrow-to-region (goto-char (point-min))
-                         (if (search-forward "\n\n" nil t)
-                             (1- (point))
-                           (point-max)))
-       (unless (mail-fetch-field "Message-ID")
-         (goto-char (point-min))
-         (insert "Message-ID: " server-id "\n"))
-       (widen))
-      (run-hooks 'nntp-prepare-post-hook)
-      (nntp-send-buffer "^[23].*\n"))))
+  (nntp-with-open-group
+   nil server
+   (when (nntp-send-command "^[23].*\r?\n" "POST")
+     (let ((response (with-current-buffer nntp-server-buffer
+                      nntp-process-response))
+          server-id)
+       (when (and response
+                 (string-match "^[23].*\\(<[^\t\n @<>]+@[^\t\n @<>]+>\\)"
+                               response))
+        (setq server-id (match-string 1 response))
+        (narrow-to-region (goto-char (point-min))
+                          (if (search-forward "\n\n" nil t)
+                              (1- (point))
+                            (point-max)))
+        (unless (mail-fetch-field "Message-ID")
+          (goto-char (point-min))
+          (insert "Message-ID: " server-id "\n"))
+        (widen))
+       (run-hooks 'nntp-prepare-post-hook)
+       (nntp-send-buffer "^[23].*\n")))))
 
 (deffoo nntp-request-type (group article)
   'news)
 
 (deffoo nntp-request-type (group article)
   'news)
@@ -1300,11 +1345,15 @@ password contained in '~/.nntp-authinfo'."
       (unless (< len 10)
        (setq nntp-have-messaged t)
        (nnheader-message 7 "nntp read: %dk" len)))
       (unless (< len 10)
        (setq nntp-have-messaged t)
        (nnheader-message 7 "nntp read: %dk" len)))
-    (accept-process-output process (or timeout 1))
-    ;; accept-process-output may update status of process to indicate that the server has closed the
-    ;; connection.  This MUST be handled here as the buffer restored by the save-excursion may be the 
-    ;; process's former output buffer (i.e. now killed)
-    (or (memq (process-status process) '(open run))
+    (if timeout
+       (accept-process-output process timeout)
+      (accept-process-output process 0 100))
+    ;; accept-process-output may update status of process to indicate
+    ;; that the server has closed the connection.  This MUST be
+    ;; handled here as the buffer restored by the save-excursion may
+    ;; be the process's former output buffer (i.e. now killed)
+    (or (and process 
+            (memq (process-status process) '(open run)))
         (nntp-report "Server closed connection"))))
 
 (defun nntp-accept-response ()
         (nntp-report "Server closed connection"))))
 
 (defun nntp-accept-response ()
@@ -1463,18 +1512,22 @@ password contained in '~/.nntp-authinfo'."
              (nntp-accept-response)
              (set-buffer process-buffer))))
 
              (nntp-accept-response)
              (set-buffer process-buffer))))
 
-        ;; Some nntp servers seem to have an extension to the XOVER extension.  On these 
-        ;; servers, requesting an article range preceeding the active range does not return an 
-        ;; error as specified in the RFC.  What we instead get is the NOV entry for the first 
-        ;; available article.  Obviously, a client can use that entry to avoid making unnecessary 
-        ;; requests.  The only problem is for a client that assumes that the response will always be
-        ;; within the requested ranage.  For such a client, we can get N copies of the same entry
-        ;; (one for each XOVER command sent to the server).
+        ;; Some nntp servers seem to have an extension to the XOVER
+        ;; extension.  On these servers, requesting an article range
+        ;; preceeding the active range does not return an error as
+        ;; specified in the RFC.  What we instead get is the NOV entry
+        ;; for the first available article.  Obviously, a client can
+        ;; use that entry to avoid making unnecessary requests.  The
+        ;; only problem is for a client that assumes that the response
+        ;; will always be within the requested ranage.  For such a
+        ;; client, we can get N copies of the same entry (one for each
+        ;; XOVER command sent to the server).
 
         (when (<= count 1)
           (goto-char (point-min))
           (when (re-search-forward "^[0-9][0-9][0-9] .*\n\\([0-9]+\\)" nil t)
 
         (when (<= count 1)
           (goto-char (point-min))
           (when (re-search-forward "^[0-9][0-9][0-9] .*\n\\([0-9]+\\)" nil t)
-            (let ((low-limit (string-to-int (buffer-substring (match-beginning 1) (match-end 1)))))
+            (let ((low-limit (string-to-int (buffer-substring (match-beginning 1) 
+                                                              (match-end 1)))))
               (while (and articles (<= (car articles) low-limit))
                 (setq articles (cdr articles))))))
         (set-buffer buf))
               (while (and articles (<= (car articles) low-limit))
                 (setq articles (cdr articles))))))
         (set-buffer buf))
index c4bc8c5..7937da5 100644 (file)
@@ -204,7 +204,7 @@ Valid types include `google', `dejanews', and `gmane'.")
   (nnweb-possibly-change-server group server))
 
 (deffoo nnweb-asynchronous-p ()
   (nnweb-possibly-change-server group server))
 
 (deffoo nnweb-asynchronous-p ()
-  t)
+  nil)
 
 (deffoo nnweb-request-create-group (group &optional server args)
   (nnweb-possibly-change-server nil server)
 
 (deffoo nnweb-request-create-group (group &optional server args)
   (nnweb-possibly-change-server nil server)
index fb1c3e5..fc134f9 100644 (file)
@@ -1,14 +1,12 @@
 ;;; spam-stat.el --- detecting spam based on statistics
 
 ;;; spam-stat.el --- detecting spam based on statistics
 
-;; Copyright (C) 2002  Alex Schroeder
+;; Copyright (C) 2002  Free Software Foundation, Inc.
 
 ;; Author: Alex Schroeder <alex@gnu.org>
 
 ;; Author: Alex Schroeder <alex@gnu.org>
-;; Maintainer: Alex Schroeder <alex@gnu.org>
-;; Version: 0.3.5
-;; Keywords: spam filtering gnus
+;; Keywords: network
 ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SpamStat
 
 ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SpamStat
 
-;; This file is NOT part of GNU Emacs.
+;; This file is part of GNU Emacs.
 
 ;; This is free software; you can redistribute it and/or modify it
 ;; under the terms of the GNU General Public License as published by
 
 ;; This is free software; you can redistribute it and/or modify it
 ;; under the terms of the GNU General Public License as published by
@@ -41,7 +39,7 @@
 ;; considered to be a new spam mail; use this for new mail that has
 ;; not been processed before
 ;;
 ;; considered to be a new spam mail; use this for new mail that has
 ;; not been processed before
 ;;
-;; `spam-stat-buffer-is-no-spam' -- called in a buffer, that buffer
+;; `spam-stat-buffer-is-non-spam' -- called in a buffer, that buffer
 ;; is considered to be a new non-spam mail; use this for new mail that
 ;; has not been processed before
 ;;
 ;; is considered to be a new non-spam mail; use this for new mail that
 ;; has not been processed before
 ;;
@@ -77,7 +75,7 @@
 
 ;; Typical test will involve calls to the following functions:
 ;;
 
 ;; Typical test will involve calls to the following functions:
 ;;
-;; Reset: (setq spam-stat (make-hash-table :test 'equal))
+;; Reset: (spam-stat-reset)
 ;; Learn spam: (spam-stat-process-spam-directory "~/Mail/mail/spam")
 ;; Learn non-spam: (spam-stat-process-non-spam-directory "~/Mail/mail/misc")
 ;; Save table: (spam-stat-save)
 ;; Learn spam: (spam-stat-process-spam-directory "~/Mail/mail/spam")
 ;; Learn non-spam: (spam-stat-process-non-spam-directory "~/Mail/mail/misc")
 ;; Save table: (spam-stat-save)
@@ -98,7 +96,7 @@
 ;; rules in `nnmail-split-fancy'.  Somewhere among these rules, you
 ;; will filter spam.  Here is how you would create your dictionary:
 
 ;; rules in `nnmail-split-fancy'.  Somewhere among these rules, you
 ;; will filter spam.  Here is how you would create your dictionary:
 
-;; Reset: (setq spam-stat (make-hash-table :test 'equal))
+;; Reset: (spam-stat-reset)
 ;; Learn spam: (spam-stat-process-spam-directory "~/Mail/mail/spam")
 ;; Learn non-spam: (spam-stat-process-non-spam-directory "~/Mail/mail/misc")
 ;; Repeat for any other non-spam group you need...
 ;; Learn spam: (spam-stat-process-spam-directory "~/Mail/mail/spam")
 ;; Learn non-spam: (spam-stat-process-non-spam-directory "~/Mail/mail/misc")
 ;; Repeat for any other non-spam group you need...
 ;; Ted Zlatanov <tzz@lifelogs.com>
 ;; Jesper Harder <harder@myrealbox.com>
 ;; Dan Schmidt <dfan@dfan.org>
 ;; Ted Zlatanov <tzz@lifelogs.com>
 ;; Jesper Harder <harder@myrealbox.com>
 ;; Dan Schmidt <dfan@dfan.org>
+;; Lasse Rasinen <lrasinen@iki.fi>
+;; Milan Zamazal <pdm@zamazal.org>
 
 \f
 
 
 \f
 
   "Statistical spam detection for Emacs.
 Use the functions to build a dictionary of words and their statistical
 distribution in spam and non-spam mails.  Then use a function to determine
   "Statistical spam detection for Emacs.
 Use the functions to build a dictionary of words and their statistical
 distribution in spam and non-spam mails.  Then use a function to determine
-wether a buffer contains spam or not."
+whether a buffer contains spam or not."
   :group 'gnus)
 
 (defcustom spam-stat-file "~/.spam-stat.el"
   :group 'gnus)
 
 (defcustom spam-stat-file "~/.spam-stat.el"
@@ -136,6 +136,12 @@ See `spam-stat-to-hash-table' for the format of the file."
   :type 'file
   :group 'spam-stat)
 
   :type 'file
   :group 'spam-stat)
 
+(defcustom spam-stat-install-hooks t
+  "Whether spam-stat should install its hooks in Gnus.
+This is set to nil if you use spam-stat through spam.el."
+  :type 'boolean
+  :group 'spam-stat)
+
 (defcustom spam-stat-unknown-word-score 0.2
   "The score to use for unknown words.
 Also used for words that don't appear often enough."
 (defcustom spam-stat-unknown-word-score 0.2
   "The score to use for unknown words.
 Also used for words that don't appear often enough."
@@ -155,10 +161,16 @@ This variable says how many characters this will be."
 
 (defcustom spam-stat-split-fancy-spam-group "mail.spam"
   "Name of the group where spam should be stored, if
 
 (defcustom spam-stat-split-fancy-spam-group "mail.spam"
   "Name of the group where spam should be stored, if
-`spam-stat-split-fancy' is used in fancy splitting rules."
+`spam-stat-split-fancy' is used in fancy splitting rules.  Has no
+effect when spam-stat is invoked through spam.el."
   :type 'string
   :group 'spam-stat)
 
   :type 'string
   :group 'spam-stat)
 
+(defcustom spam-stat-split-fancy-spam-threshhold 0.9
+  "Spam score threshhold in spam-stat-split-fancy."
+  :type 'number
+  :group 'spam-stat)
+
 (defvar spam-stat-syntax-table
   (let ((table (copy-syntax-table text-mode-syntax-table)))
     (modify-syntax-entry ?- "w" table)
 (defvar spam-stat-syntax-table
   (let ((table (copy-syntax-table text-mode-syntax-table)))
     (modify-syntax-entry ?- "w" table)
@@ -226,10 +238,11 @@ This uses `gnus-article-buffer'."
     (set-buffer gnus-original-article-buffer)
     (spam-stat-store-current-buffer)))
 
     (set-buffer gnus-original-article-buffer)
     (spam-stat-store-current-buffer)))
 
-(add-hook 'nnmail-prepare-incoming-message-hook
-         'spam-stat-store-current-buffer)
-(add-hook 'gnus-select-article-hook
-         'spam-stat-store-gnus-article-buffer)
+(when spam-stat-install-hooks
+  (add-hook 'nnmail-prepare-incoming-message-hook
+           'spam-stat-store-current-buffer)
+  (add-hook 'gnus-select-article-hook
+           'spam-stat-store-gnus-article-buffer))
 
 ;; Data -- not using defstruct in order to save space and time
 
 
 ;; Data -- not using defstruct in order to save space and time
 
@@ -386,17 +399,17 @@ Use `spam-stat-ngood', `spam-stat-nbad', `spam-stat-good',
   (interactive)
   (with-temp-buffer
     (let ((standard-output (current-buffer)))
   (interactive)
   (with-temp-buffer
     (let ((standard-output (current-buffer)))
-      (insert "(setq spam-stat (spam-stat-to-hash-table '(")
+      (insert "(setq spam-stat-ngood "
+              (number-to-string spam-stat-ngood)
+              " spam-stat-nbad "
+              (number-to-string spam-stat-nbad)
+              " spam-stat (spam-stat-to-hash-table '(")
       (maphash (lambda (word entry)
                 (prin1 (list word
                              (spam-stat-good entry)
                              (spam-stat-bad entry))))
               spam-stat)
       (maphash (lambda (word entry)
                 (prin1 (list word
                              (spam-stat-good entry)
                              (spam-stat-bad entry))))
               spam-stat)
-      (insert ")) spam-stat-ngood "
-             (number-to-string spam-stat-ngood)
-             " spam-stat-nbad "
-             (number-to-string spam-stat-nbad)
-             ")"))
+      (insert ")))"))
     (write-file spam-stat-file)))
 
 (defun spam-stat-load ()
     (write-file spam-stat-file)))
 
 (defun spam-stat-load ()
@@ -422,7 +435,9 @@ has appeared in bad mails."
   "Reset `spam-stat' to an empty hash-table.
 This deletes all the statistics."
   (interactive)
   "Reset `spam-stat' to an empty hash-table.
 This deletes all the statistics."
   (interactive)
-  (setq spam-stat (make-hash-table :test 'equal)))
+  (setq spam-stat (make-hash-table :test 'equal)
+       spam-stat-ngood 0
+       spam-stat-nbad 0))
 
 ;; Scoring buffers
 
 
 ;; Scoring buffers
 
@@ -469,7 +484,7 @@ check the variable `spam-stat-score-data'."
       (progn
        (set-buffer spam-stat-buffer)
        (goto-char (point-min))
       (progn
        (set-buffer spam-stat-buffer)
        (goto-char (point-min))
-       (when (> (spam-stat-score-buffer) 0.9)
+       (when (> (spam-stat-score-buffer) spam-stat-split-fancy-spam-threshhold)
          (when (boundp 'nnmail-split-trace)
            (mapc (lambda (entry)
                    (push entry nnmail-split-trace))
          (when (boundp 'nnmail-split-trace)
            (mapc (lambda (entry)
                    (push entry nnmail-split-trace))
index 65387d0..cb171df 100644 (file)
 
 (require 'gnus-uu)                     ; because of key prefix issues
 (require 'gnus)        ; for the definitions of group content classification and spam processors
 
 (require 'gnus-uu)                     ; because of key prefix issues
 (require 'gnus)        ; for the definitions of group content classification and spam processors
-
-;; FIXME!  We should not require `message' until we actually need
-;; them.  Best would be to declare needed functions as auto-loadable.
-(require 'message)
-
-;; Attempt to load BBDB macros
-(eval-when-compile
-  (condition-case nil
-      (require 'bbdb-com)
-    (file-error (defalias 'bbdb-search 'ignore))))
+(require 'message)                     ;for the message-fetch-field functions
 
 ;; autoload executable-find
 (eval-and-compile
   ;; executable-find is not autoloaded in Emacs 20
   (autoload 'executable-find "executable"))
 
 
 ;; autoload executable-find
 (eval-and-compile
   ;; executable-find is not autoloaded in Emacs 20
   (autoload 'executable-find "executable"))
 
-;; autoload ifile-spam-filter
-(eval-and-compile
-  (autoload 'ifile-spam-filter "ifile-gnus"))
-
 ;; autoload query-dig
 (eval-and-compile
   (autoload 'query-dig "dig"))
 ;; autoload query-dig
 (eval-and-compile
   (autoload 'query-dig "dig"))
   :type 'directory
   :group 'spam)
 
   :type 'directory
   :group 'spam)
 
+(defcustom spam-move-spam-nonspam-groups-only t
+  "Whether spam should be moved in non-spam groups only.
+When nil, only ham and unclassified groups will have their spam moved
+to the spam-process-destination.  When t, spam will also be moved from
+spam groups."
+  :type 'boolean
+  :group 'spam-ifile)
+
 (defcustom spam-whitelist (expand-file-name "whitelist" spam-directory)
   "The location of the whitelist.
 The file format is one regular expression per line.
 (defcustom spam-whitelist (expand-file-name "whitelist" spam-directory)
   "The location of the whitelist.
 The file format is one regular expression per line.
@@ -125,25 +120,31 @@ The regular expression is matched against the address."
   :type 'boolean
   :group 'spam)
 
   :type 'boolean
   :group 'spam)
 
+(defcustom spam-use-stat nil
+  "Whether spam-stat should be used by spam-split."
+  :type 'boolean
+  :group 'spam)
+
 (defcustom spam-split-group "spam"
   "Group name where incoming spam should be put by spam-split."
   :type 'string
   :group 'spam)
 
 (defcustom spam-split-group "spam"
   "Group name where incoming spam should be put by spam-split."
   :type 'string
   :group 'spam)
 
-;; FIXME!  The mailgroup list evidently depends on other choices made by the
-;; user, so the built-in default below is not likely to be appropriate.
 (defcustom spam-junk-mailgroups (cons spam-split-group '("mail.junk" "poste.pourriel"))
   "Mailgroups with spam contents.
 All unmarked article in such group receive the spam mark on group entry."
   :type '(repeat (string :tag "Group"))
   :group 'spam)
 
 (defcustom spam-junk-mailgroups (cons spam-split-group '("mail.junk" "poste.pourriel"))
   "Mailgroups with spam contents.
 All unmarked article in such group receive the spam mark on group entry."
   :type '(repeat (string :tag "Group"))
   :group 'spam)
 
-(defcustom spam-blackhole-servers '("bl.spamcop.net" "relays.ordb.org" "dev.null.dk" "relays.visi.com")
+(defcustom spam-blackhole-servers '("bl.spamcop.net" "relays.ordb.org" 
+                                   "dev.null.dk" "relays.visi.com")
   "List of blackhole servers."
   :type '(repeat (string :tag "Server"))
   :group 'spam)
 
   "List of blackhole servers."
   :type '(repeat (string :tag "Server"))
   :group 'spam)
 
-(defcustom spam-ham-marks (list 'gnus-del-mark 'gnus-read-mark 'gnus-killed-mark 'gnus-kill-file-mark 'gnus-low-score-mark)
+(defcustom spam-ham-marks (list 'gnus-del-mark 'gnus-read-mark 
+                               'gnus-killed-mark 'gnus-kill-file-mark 
+                               'gnus-low-score-mark)
   "Marks considered as being ham (positively not spam).
 Such articles will be processed as ham (non-spam) on group exit."
   :type '(set
   "Marks considered as being ham (positively not spam).
 Such articles will be processed as ham (non-spam) on group exit."
   :type '(set
@@ -169,6 +170,34 @@ Such articles will be transmitted to `bogofilter -s' on group exit."
   :type 'face
   :group 'spam)
 
   :type 'face
   :group 'spam)
 
+(defgroup spam-ifile nil
+  "Spam ifile configuration."
+  :group 'spam)
+
+(defcustom spam-ifile-path (executable-find "ifile")
+  "File path of the ifile executable program."
+  :type '(choice (file :tag "Location of ifile")
+                (const :tag "ifile is not installed"))
+  :group 'spam-ifile)
+
+(defcustom spam-ifile-database-path nil
+  "File path of the ifile database."
+  :type '(choice (file :tag "Location of the ifile database")
+                (const :tag "Use the default"))
+  :group 'spam-ifile)
+
+(defcustom spam-ifile-spam-category "spam"
+  "Name of the spam ifile category."  
+  :type 'string
+  :group 'spam-ifile)
+
+(defcustom spam-ifile-all-categories nil
+  "Whether the ifile check will return all categories, or just spam.
+Set this to t if you want to use the spam-split invocation of ifile as
+your main source of newsgroup names."
+  :type 'boolean
+  :group 'spam-ifile)
+
 (defgroup spam-bogofilter nil
   "Spam bogofilter configuration."
   :group 'spam)
 (defgroup spam-bogofilter nil
   "Spam bogofilter configuration."
   :group 'spam)
@@ -199,7 +228,8 @@ Such articles will be transmitted to `bogofilter -s' on group exit."
 ;; (and previously X-NoSpam) are produced by the `NoSpam' tool, which has
 ;; never been published, so it might not be reasonable leaving it in the
 ;; list.
 ;; (and previously X-NoSpam) are produced by the `NoSpam' tool, which has
 ;; never been published, so it might not be reasonable leaving it in the
 ;; list.
-(defcustom spam-bogofilter-spaminfo-header-regexp "^X-\\(jf\\|Junk\\|NoSpam\\|Spam\\|SB\\)[^:]*:"
+(defcustom spam-bogofilter-spaminfo-header-regexp 
+  "^X-\\(jf\\|Junk\\|NoSpam\\|Spam\\|SB\\)[^:]*:"
   "Regexp for spam markups in headers.
 Markup from spam recognisers, as well as `Xref', are to be removed from
 articles before they get registered by Bogofilter."
   "Regexp for spam markups in headers.
 Markup from spam recognisers, as well as `Xref', are to be removed from
 articles before they get registered by Bogofilter."
@@ -226,12 +256,14 @@ articles before they get registered by Bogofilter."
 (defun spam-group-spam-contents-p (group)
   (if (stringp group)
       (or (member group spam-junk-mailgroups)
 (defun spam-group-spam-contents-p (group)
   (if (stringp group)
       (or (member group spam-junk-mailgroups)
-         (memq 'gnus-group-spam-classification-spam (gnus-parameter-spam-contents group)))
+         (memq 'gnus-group-spam-classification-spam 
+               (gnus-parameter-spam-contents group)))
     nil))
   
 (defun spam-group-ham-contents-p (group)
   (if (stringp group)
     nil))
   
 (defun spam-group-ham-contents-p (group)
   (if (stringp group)
-      (memq 'gnus-group-spam-classification-ham (gnus-parameter-spam-contents group))
+      (memq 'gnus-group-spam-classification-ham 
+           (gnus-parameter-spam-contents group))
     nil))
 
 (defun spam-group-processor-p (group processor)
     nil))
 
 (defun spam-group-processor-p (group processor)
@@ -240,53 +272,84 @@ articles before they get registered by Bogofilter."
       (member processor (car (gnus-parameter-spam-process group)))
     nil))
 
       (member processor (car (gnus-parameter-spam-process group)))
     nil))
 
-(defun spam-group-processor-bogofilter-p (group)
+(defun spam-group-spam-processor-bogofilter-p (group)
   (spam-group-processor-p group 'gnus-group-spam-exit-processor-bogofilter))
 
   (spam-group-processor-p group 'gnus-group-spam-exit-processor-bogofilter))
 
-(defun spam-group-processor-ifile-p (group)
+(defun spam-group-spam-processor-blacklist-p (group)
+  (spam-group-processor-p group 'gnus-group-spam-exit-processor-blacklist))
+
+(defun spam-group-spam-processor-ifile-p (group)
   (spam-group-processor-p group 'gnus-group-spam-exit-processor-ifile))
 
   (spam-group-processor-p group 'gnus-group-spam-exit-processor-ifile))
 
-(defun spam-group-processor-blacklist-p (group)
-  (spam-group-processor-p group 'gnus-group-spam-exit-processor-blacklist))
+(defun spam-group-ham-processor-ifile-p (group)
+  (spam-group-processor-p group 'gnus-group-ham-exit-processor-ifile))
+
+(defun spam-group-spam-processor-stat-p (group)
+  (spam-group-processor-p group 'gnus-group-spam-exit-processor-stat))
 
 
-(defun spam-group-processor-whitelist-p (group)
+(defun spam-group-ham-processor-stat-p (group)
+  (spam-group-processor-p group 'gnus-group-ham-exit-processor-stat))
+
+(defun spam-group-ham-processor-whitelist-p (group)
   (spam-group-processor-p group 'gnus-group-ham-exit-processor-whitelist))
 
   (spam-group-processor-p group 'gnus-group-ham-exit-processor-whitelist))
 
-(defun spam-group-processor-BBDB-p (group)
+(defun spam-group-ham-processor-BBDB-p (group)
   (spam-group-processor-p group 'gnus-group-ham-exit-processor-BBDB))
 
   (spam-group-processor-p group 'gnus-group-ham-exit-processor-BBDB))
 
-;;; Hooks dispatching.  A bit raw for now.
+;;; Summary entry and exit processing.
 
 (defun spam-summary-prepare ()
   (spam-mark-junk-as-spam-routine))
 
 
 (defun spam-summary-prepare ()
   (spam-mark-junk-as-spam-routine))
 
+(add-hook 'gnus-summary-prepare-hook 'spam-summary-prepare)
+
 (defun spam-summary-prepare-exit ()
   ;; The spam processors are invoked for any group, spam or ham or neither
   (when (and spam-bogofilter-path
 (defun spam-summary-prepare-exit ()
   ;; The spam processors are invoked for any group, spam or ham or neither
   (when (and spam-bogofilter-path
-            (spam-group-processor-bogofilter-p gnus-newsgroup-name))
+            (spam-group-spam-processor-bogofilter-p gnus-newsgroup-name))
     (spam-bogofilter-register-routine))
   
     (spam-bogofilter-register-routine))
   
-  (when (spam-group-processor-ifile-p gnus-newsgroup-name)
-    (spam-ifile-register-routine))
+  (when (and spam-ifile-path
+            (spam-group-spam-processor-ifile-p gnus-newsgroup-name))
+    (spam-ifile-register-spam-routine))
   
   
-  (when (spam-group-processor-bogofilter-p gnus-newsgroup-name)
+  (when (spam-group-spam-processor-stat-p gnus-newsgroup-name)
+    (spam-stat-register-spam-routine))
+
+  (when (spam-group-spam-processor-bogofilter-p gnus-newsgroup-name)
     (spam-blacklist-register-routine))
 
     (spam-blacklist-register-routine))
 
-  ;; Only for spam groups, we expire and maybe move articles
-  (when (spam-group-spam-contents-p gnus-newsgroup-name)
-    (spam-mark-spam-as-expired-and-move-routine (gnus-parameter-spam-process-destination gnus-newsgroup-name)))
+  (if spam-move-spam-nonspam-groups-only      
+      (when (not (spam-group-spam-contents-p gnus-newsgroup-name))
+       (spam-mark-spam-as-expired-and-move-routine
+        (gnus-parameter-spam-process-destination gnus-newsgroup-name)))
+    (spam-mark-spam-as-expired-and-move-routine 
+     (gnus-parameter-spam-process-destination gnus-newsgroup-name)))
+
+  ;; now we redo spam-mark-spam-as-expired-and-move-routine to only
+  ;; expire spam, in case the above did not expire them
+  (spam-mark-spam-as-expired-and-move-routine nil)
 
   (when (spam-group-ham-contents-p gnus-newsgroup-name)
 
   (when (spam-group-ham-contents-p gnus-newsgroup-name)
-    (when (spam-group-processor-whitelist-p gnus-newsgroup-name)
+    (when (spam-group-ham-processor-whitelist-p gnus-newsgroup-name)
       (spam-whitelist-register-routine))
       (spam-whitelist-register-routine))
-    (when (spam-group-processor-BBDB-p gnus-newsgroup-name)
-      (spam-BBDB-register-routine))))
+    (when (spam-group-ham-processor-ifile-p gnus-newsgroup-name)
+      (spam-ifile-register-ham-routine))
+    (when (spam-group-ham-processor-stat-p gnus-newsgroup-name)
+      (spam-stat-register-ham-routine))
+    (when (spam-group-ham-processor-BBDB-p gnus-newsgroup-name)
+      (spam-BBDB-register-routine)))
+
+  ;; now move all ham articles out of spam groups
+  (when (spam-group-spam-contents-p gnus-newsgroup-name)
+    (spam-ham-move-routine
+     (gnus-parameter-ham-process-destination gnus-newsgroup-name))))
 
 
-(add-hook 'gnus-summary-prepare-hook 'spam-summary-prepare)
 (add-hook 'gnus-summary-prepare-exit-hook 'spam-summary-prepare-exit)
 
 (defun spam-mark-junk-as-spam-routine ()
 (add-hook 'gnus-summary-prepare-exit-hook 'spam-summary-prepare-exit)
 
 (defun spam-mark-junk-as-spam-routine ()
-  ;; check the global list of group names spam-junk-mailgroups and the group parameters
+  ;; check the global list of group names spam-junk-mailgroups and the
+  ;; group parameters
   (when (spam-group-spam-contents-p gnus-newsgroup-name)
     (let ((articles gnus-newsgroup-articles)
          article)
   (when (spam-group-spam-contents-p gnus-newsgroup-name)
     (let ((articles gnus-newsgroup-articles)
          article)
@@ -306,12 +369,27 @@ articles before they get registered by Bogofilter."
          (let ((gnus-current-article article))
            (gnus-summary-move-article nil group)))))))
  
          (let ((gnus-current-article article))
            (gnus-summary-move-article nil group)))))))
  
+(defun spam-ham-move-routine (&optional group)
+  (let ((articles gnus-newsgroup-articles)
+       article ham-mark-values mark)
+    (dolist (mark spam-ham-marks)
+      (push (symbol-value mark) ham-mark-values))
+
+    (while articles
+      (setq article (pop articles))
+      (when (and (memq mark ham-mark-values)
+                (stringp group))
+         (let ((gnus-current-article article))
+           (gnus-summary-move-article nil group))))))
 (defun spam-generic-register-routine (spam-func ham-func)
   (let ((articles gnus-newsgroup-articles)
 (defun spam-generic-register-routine (spam-func ham-func)
   (let ((articles gnus-newsgroup-articles)
-       article mark ham-articles spam-articles spam-mark-values ham-mark-values)
+       article mark ham-articles spam-articles spam-mark-values 
+       ham-mark-values)
 
 
-    ;; marks are stored as symbolic values, so we have to dereference them for memq to work
-    ;; we wouldn't have to do this if gnus-summary-article-mark returned a symbol.
+    ;; marks are stored as symbolic values, so we have to dereference
+    ;; them for memq to work.  we wouldn't have to do this if
+    ;; gnus-summary-article-mark returned a symbol.
     (dolist (mark spam-ham-marks)
       (push (symbol-value mark) ham-mark-values))
 
     (dolist (mark spam-ham-marks)
       (push (symbol-value mark) ham-mark-values))
 
@@ -325,17 +403,43 @@ articles before they get registered by Bogofilter."
            ((memq article gnus-newsgroup-saved))
            ((memq mark ham-mark-values) (push article ham-articles))))
     (when (and ham-articles ham-func)
            ((memq article gnus-newsgroup-saved))
            ((memq mark ham-mark-values) (push article ham-articles))))
     (when (and ham-articles ham-func)
-      (mapc ham-func ham-articles))    ; we use mapc because unlike mapcar it discards the return values
+      (mapc ham-func ham-articles))    ; we use mapc because unlike
+                                       ; mapcar it discards the
+                                       ; return values
     (when (and spam-articles spam-func)
     (when (and spam-articles spam-func)
-      (mapc spam-func spam-articles))))        ; we use mapc because unlike mapcar it discards the return values
+      (mapc spam-func spam-articles))))        ; we use mapc because unlike
+                                       ; mapcar it discards the
+                                       ; return values
+
+(eval-and-compile
+  (defalias 'spam-point-at-eol (if (fboundp 'point-at-eol)
+                                  'point-at-eol
+                                'line-end-position)))
+
+(defun spam-get-article-as-string (article)
+  (let ((article-string))
+    (when (numberp article)
+      (save-window-excursion
+       (gnus-summary-goto-subject article)
+       (gnus-summary-show-article t)
+       (set-buffer gnus-article-buffer)
+       (setq article-string (buffer-string))))
+    article-string))
 
 (defun spam-fetch-field-from-fast (article)
 
 (defun spam-fetch-field-from-fast (article)
-  "Fetch the `from' field quickly, using the Gnus internal gnus-data-list function"
+  "Fetch the `from' field quickly, using the internal gnus-data-list function"
   (if (and (numberp article)
           (assoc article (gnus-data-list nil)))
       (mail-header-from (gnus-data-header (assoc article (gnus-data-list nil))))
     nil))
 
   (if (and (numberp article)
           (assoc article (gnus-data-list nil)))
       (mail-header-from (gnus-data-header (assoc article (gnus-data-list nil))))
     nil))
 
+(defun spam-fetch-field-subject-fast (article)
+  "Fetch the `subject' field quickly, using the internal gnus-data-list function"
+  (if (and (numberp article)
+          (assoc article (gnus-data-list nil)))
+      (mail-header-subject (gnus-data-header (assoc article (gnus-data-list nil))))
+    nil))
+
 \f
 ;;;; Spam determination.
 
 \f
 ;;;; Spam determination.
 
@@ -344,6 +448,7 @@ articles before they get registered by Bogofilter."
     (spam-use-whitelist  . spam-check-whitelist)
     (spam-use-BBDB      . spam-check-BBDB)
     (spam-use-ifile     . spam-check-ifile)
     (spam-use-whitelist  . spam-check-whitelist)
     (spam-use-BBDB      . spam-check-BBDB)
     (spam-use-ifile     . spam-check-ifile)
+    (spam-use-stat      . spam-check-stat)
     (spam-use-blackholes . spam-check-blackholes)
     (spam-use-bogofilter . spam-check-bogofilter))
 "The spam-list-of-checks list contains pairs associating a parameter
     (spam-use-blackholes . spam-check-blackholes)
     (spam-use-bogofilter . spam-check-bogofilter))
 "The spam-list-of-checks list contains pairs associating a parameter
@@ -365,6 +470,9 @@ example like this: (: spam-split)
 
 See the Info node `(gnus)Fancy Mail Splitting' for more details."
   (interactive)
 
 See the Info node `(gnus)Fancy Mail Splitting' for more details."
   (interactive)
+  
+  ;; load the spam-stat tables if needed
+  (when spam-use-stat (spam-stat-load))
 
   (let ((list-of-checks spam-list-of-checks)
        decision)
 
   (let ((list-of-checks spam-list-of-checks)
        decision)
@@ -399,7 +507,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
            (if spam-use-dig
                (let ((query-result (query-dig query-string)))
                  (when query-result
            (if spam-use-dig
                (let ((query-result (query-dig query-string)))
                  (when query-result
-                   (message "spam detected with blackhole check of relay %s (dig query result '%s')" query-string query-result)
+                   (message "spam: positive blackhole check '%s'" query-result)
                    (push (list ip server query-result)
                          matches)))
              ;; else, if not using dig.el
                    (push (list ip server query-result)
                          matches)))
              ;; else, if not using dig.el
@@ -409,66 +517,169 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
     (when matches
       spam-split-group)))
 \f
     (when matches
       spam-split-group)))
 \f
-;;;; BBDB
-;;; original idea for spam-check-BBDB from Alexander Kotelnikov <sacha@giotto.sj.ru>
+;;;; BBDB 
+
+;;; original idea for spam-check-BBDB from Alexander Kotelnikov
+;;; <sacha@giotto.sj.ru>
 
 ;; all this is done inside a condition-case to trap errors
 
 ;; all this is done inside a condition-case to trap errors
+
 (condition-case nil
     (progn
 (condition-case nil
     (progn
-
+      (require 'bbdb)
       (require 'bbdb-com)
       (require 'bbdb-com)
-
-      (defun spam-enter-ham-BBDB (from)
-       "Enter an address into the BBDB; implies ham (non-spam) sender"
-       (when (stringp from)
-         (let* ((parsed-address (gnus-extract-address-components from))
-                (name (or (car parsed-address) "Ham Sender"))
-                (net-address (car (cdr parsed-address))))
-           (message "Adding address %s to BBDB" from)
-           (when (and net-address
-                      (not (bbdb-search (bbdb-records) nil nil net-address)))
-             (bbdb-create-internal name nil net-address nil nil "ham sender added by spam.el")))))
-
-      (defun spam-BBDB-register-routine ()
-       (spam-generic-register-routine 
-        ;; spam function
-        nil
-        ;; ham function
-        (lambda (article)
-          (spam-enter-ham-BBDB (spam-fetch-field-from-fast article)))))
-
-      (defun spam-check-BBDB ()
-       "Mail from people in the BBDB is never considered spam"
-       (let ((who (message-fetch-field "from")))
-         (when who
-           (setq who (regexp-quote (cadr (gnus-extract-address-components who))))
-           (if (bbdb-search (bbdb-records) nil nil who) nil spam-split-group)))))
+      
+  (defun spam-enter-ham-BBDB (from)
+    "Enter an address into the BBDB; implies ham (non-spam) sender"
+    (when (stringp from)
+      (let* ((parsed-address (gnus-extract-address-components from))
+            (name (or (car parsed-address) "Ham Sender"))
+            (net-address (car (cdr parsed-address))))
+       (message "Adding address %s to BBDB" from)
+       (when (and net-address
+                  (not (bbdb-search-simple nil net-address)))
+         (bbdb-create-internal name nil net-address nil nil 
+                               "ham sender added by spam.el")))))
+
+  (defun spam-BBDB-register-routine ()
+    (spam-generic-register-routine 
+     ;; spam function
+     nil
+     ;; ham function
+     (lambda (article)
+       (spam-enter-ham-BBDB (spam-fetch-field-from-fast article)))))
+
+  (defun spam-check-BBDB ()
+    "Mail from people in the BBDB is never considered spam"
+    (let ((who (message-fetch-field "from")))
+      (when who
+       (setq who (regexp-quote (cadr
+                                (gnus-extract-address-components who))))
+       (if (bbdb-search-simple nil who)
+           nil spam-split-group)))))
 
   (file-error (progn
 
   (file-error (progn
-               (setq spam-list-of-checks
-                     (delete (assoc 'spam-use-BBDB spam-list-of-checks)
-                             spam-list-of-checks))
-               (defun spam-check-BBDB ()
-                 message "spam-check-BBDB was invoked, but it shouldn't have")
-               (defun spam-BBDB-register-routine ()
-                 (spam-generic-register-routine nil nil)))))
+               (defalias 'bbdb-search-simple 'ignore)
+               (defalias 'spam-check-BBDB 'ignore)
+               (defalias 'spam-BBDB-register-routine 'ignore)
+               (defalias 'spam-enter-ham-BBDB 'ignore)
+               (defalias 'bbdb-create-internal 'ignore)
+               (defalias 'bbdb-records 'ignore))))
 
 \f
 ;;;; ifile
 
 \f
 ;;;; ifile
-;;; uses ifile-gnus.el from http://www.ai.mit.edu/people/jhbrown/ifile-gnus.html
-;;; check the ifile backend; return nil if the mail was NOT classified as spam
-;;; TODO: we can't (require 'ifile-gnus), because it will insinuate itself automatically
+
+;;; check the ifile backend; return nil if the mail was NOT classified
+;;; as spam
+
+(defun spam-get-ifile-database-parameter ()
+  "Get the command-line parameter for ifile's database from spam-ifile-database-path."
+  (if spam-ifile-database-path
+      (format "--db-file=%s" spam-ifile-database-path)
+    nil))
+    
 (defun spam-check-ifile ()
 (defun spam-check-ifile ()
-  (let ((ifile-primary-spam-group spam-split-group))
-    (ifile-spam-filter nil)))
+  "Check the ifile backend for the classification of this message"
+  (let ((article-buffer-name (buffer-name)) 
+       category return)
+    (with-temp-buffer
+      (let ((temp-buffer-name (buffer-name))
+           (db-param (spam-get-ifile-database-parameter)))
+       (save-excursion
+         (set-buffer article-buffer-name)
+         (if db-param
+             (call-process-region (point-min) (point-max) spam-ifile-path
+                                  nil temp-buffer-name nil "-q" "-c" db-param)
+           (call-process-region (point-min) (point-max) spam-ifile-path
+                                nil temp-buffer-name nil "-q" "-c")))
+       (goto-char (point-min))
+       (if (not (eobp))
+           (setq category (buffer-substring (point) (spam-point-at-eol))))
+       (when (not (zerop (length category))) ; we need a category here
+         (if spam-ifile-all-categories
+             (setq return category)
+           ;; else, if spam-ifile-all-categories is not set...
+           (when (string-equal spam-ifile-spam-category category)
+             (setq return spam-split-group))))))
+    return))
+
+(defun spam-ifile-register-with-ifile (article-string category)
+  "Register an article, given as a string, with a category.
+Uses `gnus-newsgroup-name' if category is nil (for ham registration)."
+  (when (stringp article-string)
+    (let ((category (or category gnus-newsgroup-name))
+          (db-param (spam-get-ifile-database-parameter)))
+      (with-temp-buffer
+       (insert-string article-string)
+       (if db-param
+            (call-process-region (point-min) (point-max) spam-ifile-path 
+                                 nil nil nil 
+                                 "-h" "-i" category db-param)
+          (call-process-region (point-min) (point-max) spam-ifile-path 
+                               nil nil nil 
+                               "-h" "-i" category))))))
+
+(defun spam-ifile-register-spam-routine ()
+  (spam-generic-register-routine 
+   (lambda (article)
+     (spam-ifile-register-with-ifile 
+      (spam-get-article-as-string article) spam-ifile-spam-category))
+   nil))
 
 
-;; TODO: add ifile registration 
-;; We need ifile-gnus.el to support nnimap; we could feel the message
-;; directly to ifile like we do with bogofilter but that's ugly.
-(defun spam-ifile-register-routine ()
-  (spam-generic-register-routine nil nil))
+(defun spam-ifile-register-ham-routine ()
+  (spam-generic-register-routine 
+   nil
+   (lambda (article)
+     (spam-ifile-register-with-ifile 
+      (spam-get-article-as-string article) nil))))
 
 \f
 
 \f
+;;;; spam-stat
+
+(condition-case nil
+    (progn
+      (let ((spam-stat-install-hooks nil))
+       (require 'spam-stat))
+      
+      (defun spam-check-stat ()
+       "Check the spam-stat backend for the classification of this message"
+       (let ((spam-stat-split-fancy-spam-group spam-split-group) ; override
+             (spam-stat-buffer (buffer-name)) ; stat the current buffer
+             category return)
+         (spam-stat-split-fancy)))
+
+      (defun spam-stat-register-spam-routine ()
+       (spam-generic-register-routine 
+        (lambda (article)
+          (let ((article-string (spam-get-article-as-string article)))
+            (with-temp-buffer
+              (insert-string article-string)
+              (spam-stat-buffer-is-spam))))
+        nil)
+       (spam-stat-save))
+
+      (defun spam-stat-register-ham-routine ()
+       (spam-generic-register-routine 
+        nil
+        (lambda (article)
+          (let ((article-string (spam-get-article-as-string article)))
+            (with-temp-buffer
+              (insert-string article-string)
+              (spam-stat-buffer-is-non-spam)))))
+       (spam-stat-save)))
+
+  (file-error (progn
+               (defalias 'spam-stat-register-ham-routine 'ignore)
+               (defalias 'spam-stat-register-spam-routine 'ignore)
+               (defalias 'spam-stat-buffer-is-spam 'ignore)
+               (defalias 'spam-stat-buffer-is-non-spam 'ignore)
+               (defalias 'spam-stat-split-fancy 'ignore)
+               (defalias 'spam-stat-load 'ignore)
+               (defalias 'spam-stat-save 'ignore)
+               (defalias 'spam-check-stat 'ignore))))
+
+\f
+
 ;;;; Blacklists and whitelists.
 
 (defvar spam-whitelist-cache nil)
 ;;;; Blacklists and whitelists.
 
 (defvar spam-whitelist-cache nil)
@@ -512,11 +723,6 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
     (setq spam-blacklist-cache (spam-parse-list spam-blacklist)))
   (and (spam-from-listed-p spam-blacklist-cache) spam-split-group))
 
     (setq spam-blacklist-cache (spam-parse-list spam-blacklist)))
   (and (spam-from-listed-p spam-blacklist-cache) spam-split-group))
 
-(eval-and-compile
-  (defalias 'spam-point-at-eol (if (fboundp 'point-at-eol)
-                                  'point-at-eol
-                                'line-end-position)))
-
 (defun spam-parse-list (file)
   (when (file-readable-p file)
     (let (contents address)
 (defun spam-parse-list (file)
   (when (file-readable-p file)
     (let (contents address)
@@ -566,14 +772,15 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
 
 ;;; See Paul Graham article, at `http://www.paulgraham.com/spam.html'.
 
 
 ;;; See Paul Graham article, at `http://www.paulgraham.com/spam.html'.
 
-;;; This page is for those wanting to control spam with the help of Eric
-;;; Raymond's speedy Bogofilter, see http://www.tuxedo.org/~esr/bogofilter.
-;;; This has been tested with a locally patched copy of version 0.4.
+;;; This page is for those wanting to control spam with the help of
+;;; Eric Raymond's speedy Bogofilter, see
+;;; http://www.tuxedo.org/~esr/bogofilter.  This has been tested with
+;;; a locally patched copy of version 0.4.
 
 
-;;; Make sure Bogofilter is installed.  Bogofilter internally uses Judy fast
-;;; associative arrays, so you need to install Judy first, and Bogofilter
-;;; next.  Fetch both distributions by visiting the following links and
-;;; downloading the latest version of each:
+;;; Make sure Bogofilter is installed.  Bogofilter internally uses
+;;; Judy fast associative arrays, so you need to install Judy first,
+;;; and Bogofilter next.  Fetch both distributions by visiting the
+;;; following links and downloading the latest version of each:
 ;;;
 ;;;     http://sourceforge.net/projects/judy/
 ;;;     http://www.tuxedo.org/~esr/bogofilter/
 ;;;
 ;;;     http://sourceforge.net/projects/judy/
 ;;;     http://www.tuxedo.org/~esr/bogofilter/
@@ -584,14 +791,15 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
 ;;;     make
 ;;;     make install
 ;;;
 ;;;     make
 ;;;     make install
 ;;;
-;;; You will likely need to become super-user for the last step.  Then, unpack
-;;; the Bogofilter distribution and enter its main directory:
+;;; You will likely need to become super-user for the last step.
+;;; Then, unpack the Bogofilter distribution and enter its main
+;;; directory:
 ;;;
 ;;;     make
 ;;;     make install
 ;;;
 ;;;
 ;;;     make
 ;;;     make install
 ;;;
-;;; Here as well, you need to become super-user for the last step.  Now,
-;;; initialize your word lists by doing, under your own identity:
+;;; Here as well, you need to become super-user for the last step.
+;;; Now, initialize your word lists by doing, under your own identity:
 ;;;
 ;;;     mkdir ~/.bogofilter
 ;;;     touch ~/.bogofilter/badlist
 ;;;
 ;;;     mkdir ~/.bogofilter
 ;;;     touch ~/.bogofilter/badlist
@@ -599,52 +807,59 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
 ;;;
 ;;; These two files are text files you may edit, but you normally don't!
 
 ;;;
 ;;; These two files are text files you may edit, but you normally don't!
 
-;;; The `M-d' command gets added to Gnus summary mode, marking current article
-;;; as spam, showing it with the `H' mark.  Whenever you see a spam article,
-;;; make sure to mark its summary line with `M-d' before leaving the group.
-;;; Some groups, as per variable `spam-junk-mailgroups' below, receive articles
-;;; from Gnus splitting on clues added by spam recognisers, so for these
-;;; groups, we tack an `H' mark at group entry for all summary lines which
-;;; would otherwise have no other mark.  Make sure to _remove_ `H' marks for
-;;; any article which is _not_ genuine spam, before leaving such groups: you
-;;; may use `M-u' to "unread" the article, or `d' for declaring it read the
-;;; non-spam way.  When you leave a group, all `H' marked articles, saved or
-;;; unsaved, are sent to Bogofilter which will study them as spam samples.
+;;; The `M-d' command gets added to Gnus summary mode, marking current
+;;; article as spam, showing it with the `H' mark.  Whenever you see a
+;;; spam article, make sure to mark its summary line with `M-d' before
+;;; leaving the group.  Some groups, as per variable
+;;; `spam-junk-mailgroups' below, receive articles from Gnus splitting
+;;; on clues added by spam recognisers, so for these groups, we tack
+;;; an `H' mark at group entry for all summary lines which would
+;;; otherwise have no other mark.  Make sure to _remove_ `H' marks for
+;;; any article which is _not_ genuine spam, before leaving such
+;;; groups: you may use `M-u' to "unread" the article, or `d' for
+;;; declaring it read the non-spam way.  When you leave a group, all
+;;; `H' marked articles, saved or unsaved, are sent to Bogofilter
+;;; which will study them as spam samples.
 
 ;;; Messages may also be deleted in various other ways, and unless
 
 ;;; Messages may also be deleted in various other ways, and unless
-;;; `spam-ham-marks-form' gets overridden below, marks `R' and `r' for default
-;;; read or explicit delete, marks `X' and 'K' for automatic or explicit
-;;; kills, as well as mark `Y' for low scores, are all considered to be
-;;; associated with articles which are not spam.  This assumption might be
-;;; false, in particular if you use kill files or score files as means for
-;;; detecting genuine spam, you should then adjust `spam-ham-marks-form'.  When
-;;; you leave a group, all _unsaved_ articles bearing any the above marks are
-;;; sent to Bogofilter which will study these as not-spam samples.  If you
-;;; explicit kill a lot, you might sometimes end up with articles marked `K'
-;;; which you never saw, and which might accidentally contain spam.  Best is
-;;; to make sure that real spam is marked with `H', and nothing else.
-
-;;; All other marks do not contribute to Bogofilter pre-conditioning.  In
-;;; particular, ticked, dormant or souped articles are likely to contribute
-;;; later, when they will get deleted for real, so there is no need to use
-;;; them prematurely.  Explicitly expired articles do not contribute, command
-;;; `E' is a way to get rid of an article without Bogofilter ever seeing it.
-
-;;; In a word, with a minimum of care for associating the `H' mark for spam
-;;; articles only, Bogofilter training all gets fairly automatic.  You should
-;;; do this until you get a few hundreds of articles in each category, spam
-;;; or not.  The shell command `head -1 ~/.bogofilter/*' shows both article
-;;; counts.  The command `S S' in summary mode, either for debugging or for
-;;; curiosity, triggers Bogofilter into displaying in another buffer the
-;;; "spamicity" score of the current article (between 0.0 and 1.0), together
-;;; with the article words which most significantly contribute to the score.
-
-;;; The real way for using Bogofilter, however, is to have some use tool like
-;;; `procmail' for invoking it on message reception, then adding some
-;;; recognisable header in case of detected spam.  Gnus splitting rules might
-;;; later trip on these added headers and react by sorting such articles into
-;;; specific junk folders as per `spam-junk-mailgroups'.  Here is a possible
-;;; `.procmailrc' contents (still untested -- please tell me how it goes):
+;;; `spam-ham-marks-form' gets overridden below, marks `R' and `r' for
+;;; default read or explicit delete, marks `X' and 'K' for automatic
+;;; or explicit kills, as well as mark `Y' for low scores, are all
+;;; considered to be associated with articles which are not spam.
+;;; This assumption might be false, in particular if you use kill
+;;; files or score files as means for detecting genuine spam, you
+;;; should then adjust `spam-ham-marks-form'.  When you leave a group,
+;;; all _unsaved_ articles bearing any the above marks are sent to
+;;; Bogofilter which will study these as not-spam samples.  If you
+;;; explicit kill a lot, you might sometimes end up with articles
+;;; marked `K' which you never saw, and which might accidentally
+;;; contain spam.  Best is to make sure that real spam is marked with
+;;; `H', and nothing else.
+
+;;; All other marks do not contribute to Bogofilter pre-conditioning.
+;;; In particular, ticked, dormant or souped articles are likely to
+;;; contribute later, when they will get deleted for real, so there is
+;;; no need to use them prematurely.  Explicitly expired articles do
+;;; not contribute, command `E' is a way to get rid of an article
+;;; without Bogofilter ever seeing it.
+
+;;; In a word, with a minimum of care for associating the `H' mark for
+;;; spam articles only, Bogofilter training all gets fairly automatic.
+;;; You should do this until you get a few hundreds of articles in
+;;; each category, spam or not.  The shell command `head -1
+;;; ~/.bogofilter/*' shows both article counts.  The command `S S' in
+;;; summary mode, either for debugging or for curiosity, triggers
+;;; Bogofilter into displaying in another buffer the "spamicity" score
+;;; of the current article (between 0.0 and 1.0), together with the
+;;; article words which most significantly contribute to the score.
+
+;;; The real way for using Bogofilter, however, is to have some use
+;;; tool like `procmail' for invoking it on message reception, then
+;;; adding some recognisable header in case of detected spam.  Gnus
+;;; splitting rules might later trip on these added headers and react
+;;; by sorting such articles into specific junk folders as per
+;;; `spam-junk-mailgroups'.  Here is a possible `.procmailrc' contents
+;;; (still untested -- please tell me how it goes):
 ;;;
 ;;; :0HBf:
 ;;; * ? bogofilter
 ;;;
 ;;; :0HBf:
 ;;; * ? bogofilter
@@ -681,10 +896,12 @@ spamicity coefficient of each, and the overall article spamicity."
 
 (defun spam-bogofilter-register-routine ()
   (let ((articles gnus-newsgroup-articles)
 
 (defun spam-bogofilter-register-routine ()
   (let ((articles gnus-newsgroup-articles)
-       article mark ham-articles spam-articles spam-mark-values ham-mark-values)
+       article mark ham-articles spam-articles spam-mark-values 
+       ham-mark-values)
 
 
-    ;; marks are stored as symbolic values, so we have to dereference them for memq to work
-    ;; we wouldn't have to do this if gnus-summary-article-mark returned a symbol.
+    ;; marks are stored as symbolic values, so we have to dereference
+    ;; them for memq to work we wouldn't have to do this if
+    ;; gnus-summary-article-mark returned a symbol.
     (dolist (mark spam-ham-marks)
       (push (symbol-value mark) ham-mark-values))
 
     (dolist (mark spam-ham-marks)
       (push (symbol-value mark) ham-mark-values))
 
@@ -705,7 +922,8 @@ spamicity coefficient of each, and the overall article spamicity."
 (defun spam-bogofilter-articles (type option articles)
   (let ((output-buffer (get-buffer-create spam-bogofilter-output-buffer-name))
        (article-copy (get-buffer-create " *Bogofilter Article Copy*"))
 (defun spam-bogofilter-articles (type option articles)
   (let ((output-buffer (get-buffer-create spam-bogofilter-output-buffer-name))
        (article-copy (get-buffer-create " *Bogofilter Article Copy*"))
-       (remove-regexp (concat spam-bogofilter-spaminfo-header-regexp "\\|Xref:"))
+       (remove-regexp (concat spam-bogofilter-spaminfo-header-regexp 
+                              "\\|Xref:"))
        (counter 0)
        prefix process article)
     (when type
        (counter 0)
        prefix process article)
     (when type
index db01533..a96296f 100644 (file)
@@ -1,3 +1,111 @@
+2003-01-11  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * message.texi (Header Commands): Addition.
+
+2003-01-10  Reiner Steib  <Reiner.Steib@gmx.de>
+
+       * gnus.texi (Article Washing): Added gnus-outlook-unwrap-lines,
+       gnus-outlook-repair-attribution, gnus-outlook-rearrange-citation.
+
+2003-01-11  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus.texi: Change .gnus to .gnus.el.
+       (Agent Commands): Remove batch here.
+       (MIME Commands): Add.
+
+       * message.texi (Canceling News): Document canlock.
+
+2003-01-10  Alex Schroeder  <alex@emacswiki.org>
+
+       * gnus.texi (Creating a spam-stat dictionary): Explain how using
+       the Gnus Agent with nnimap might work to do this.
+       (Splitting mail using spam-stat): Use nnimap-split-fancy if you
+       use the nnimap back end.
+
+2003-01-10  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * gnus.texi (Filtering Spam Using spam.el): Trivial fix.
+
+2003-01-10  Simon Josefsson  <jas@extundo.com>
+
+       * gnus.texi (Choosing Variables, Agent Caveats): Add.
+
+2003-01-09  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * gnus.texi (Filtering Spam Using spam.el, ifile spam filtering) 
+       (spam-stat spam filtering): added new functionality and explained
+       old functionality better, especially where it has changed in
+       ham/spam/unclassified group exit processing.
+
+2003-01-09  Alex Schroeder  <alex@emacswiki.org>
+
+       * gnus.texi (Splitting mail using spam-stat): Fix typo.
+       (Creating a spam-stat dictionary, Splitting mail using spam-stat):
+       Fix markup in a few places.
+
+2003-01-08  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus.texi (Positioning Point): %~ => ~*.
+
+2003-01-07  Reiner Steib  <Reiner.Steib@gmx.de>
+
+       * message.texi: Updated copyright line.
+       (Mailing Lists): Updated (renamed) function names.
+       (Header Commands): Updated (renamed) function names.
+       (Header Commands): Added message-to-list-only,
+       message-change-subject, message-cross-post-followup-to,
+       message-reduce-to-to-cc and message-add-archive-header.  Moved
+       message-sort-headers, message-insert-to, message-insert-newsgroups
+       and message-insert-disposition-notification-to from other
+       sections.
+       (Insertion): Added message-mark-inserted-region,
+       message-mark-insert-file.  Moved
+       message-insert-disposition-notification-to to section (Header
+       Commands).
+       (Various Commands): Moved message-insert-wide-reply,
+       message-insert-to, message-insert-newsgroups and
+       message-sort-headers to (Header Commands) section.
+       (Message Headers): Added message-subject-trailing-was-query.
+       (Insertion Variables): Added message-mark-insert-begin and
+       message-mark-insert-end.
+
+2003-01-08  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus.texi (Optional Back End Functions): Addition.
+       (Positioning Point): Changed to %~.
+
+2003-01-08  Simon Josefsson  <jas@extundo.com>
+
+       * gnus.texi (MIME Commands): Add.
+
+2003-01-06  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * message.texi (Various Commands): Addition.
+
+2003-01-05  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * gnus.texi (Filtering Spam Using spam.el) 
+       (Blacklists and Whitelists, BBDB Whitelists, Blackholes) 
+       (Bogofilter, Ifile spam filtering, Extending spam.el): updated
+       documentation for the new spam.el functionality
+
+2003-01-05  Jesper Harder  <harder@ifa.au.dk>
+
+       * refcard.tex: Fix pagebreak.
+
+       * gnusref.tex: Additions and fixes.
+
+       * booklet.tex: Add missing sections.
+
+       * gnus.texi (Mail Group Commands): Fix typo.
+       (XEmacs): Add sh-script.
+       (Article Washing): Fix.
+
+2003-01-05  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus.texi (Setting Process Marks): Addition.
+       (Group Line Specification): Addition.
+
 2003-01-04  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
        * gnus.texi (Group Line Specification): Addition.
 2003-01-04  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
        * gnus.texi (Group Line Specification): Addition.
index 5ae0821..b6ee207 100644 (file)
@@ -43,7 +43,7 @@
     \GroupTopicsGeneral
     \subsubsection*{Topic Sorting}
     \TopicSorting
     \GroupTopicsGeneral
     \subsubsection*{Topic Sorting}
     \TopicSorting
-%
+\pagebreak
 % summary-mode
 \section*{Summary-Mode}
 \SummaryModeGeneral
 % summary-mode
 \section*{Summary-Mode}
 \SummaryModeGeneral
 \ArticleModeGeneral
     \subsection*{Wash the Article-Buffer}
     \WashArticle
 \ArticleModeGeneral
     \subsection*{Wash the Article-Buffer}
     \WashArticle
+    \subsubsection*{Blank Lines and Whitespace}
+    \BlankAndWhitespace
+    \subsubsection*{Picons, X-faces, Smileys}
+    \Picons
+    \subsubsection*{Time and Date}
+    \TimeAndDate
     \subsection*{Hide/Highlight Parts of the Article}
     \HideHighlightArticle
     \subsection*{MIME operations from the Article-Buffer (reading)}
     \subsection*{Hide/Highlight Parts of the Article}
     \HideHighlightArticle
     \subsection*{MIME operations from the Article-Buffer (reading)}
index 5099ad4..b502cba 100644 (file)
 
 \thispagestyle{empty}
 
 
 \thispagestyle{empty}
 
-Copyright \copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+Copyright \copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003
 Free Software Foundation, Inc.
 
 
 Free Software Foundation, Inc.
 
 
@@ -336,7 +337,7 @@ This file documents gnus, the GNU Emacs newsreader.
 
 \e$B$3$N%U%!%$%k$O\e(B GNU Emacs \e$B$N%K%e!<%9%j!<%@$G$"$k\e(B gnus \e$B$K4X$9$k@bL@=q$G$9!#\e(B
 
 
 \e$B$3$N%U%!%$%k$O\e(B GNU Emacs \e$B$N%K%e!<%9%j!<%@$G$"$k\e(B gnus \e$B$K4X$9$k@bL@=q$G$9!#\e(B
 
-Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
         Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
         Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
@@ -384,7 +385,8 @@ license to the document, as described in section 6 of the license.
 @page
 
 @vskip 0pt plus 1filll
 @page
 
 @vskip 0pt plus 1filll
-Copyright @copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+Copyright @copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003
         Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
         Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
@@ -689,7 +691,7 @@ Article Treatment
 * Article Washing::             \e$B?M@8$r$b$C$H$h$/$9$k$?$/$5$s$N5$$NMx$$$?\e(B
                                 \e$B4X?t\e(B
 * Article Header::              \e$B%X%C%@!<$r$$$m$$$mJQ7A$5$;$k\e(B
 * Article Washing::             \e$B?M@8$r$b$C$H$h$/$9$k$?$/$5$s$N5$$NMx$$$?\e(B
                                 \e$B4X?t\e(B
 * Article Header::              \e$B%X%C%@!<$r$$$m$$$mJQ7A$5$;$k\e(B
-* Article Buttons::             URL \e$B$d\e(B Message-ID \e$B$d\e(B \e$B%"%I%l%9$J$I$r%/%j%C\e(B
+* Article Buttons::             URL \e$B$d\e(B Message-ID \e$B$d%"%I%l%9$J$I$r%/%j%C\e(B
                                 \e$B%/$9$k\e(B
 * Article Date::                \e$B$0$:$0$:8@$&$J!"@$3&;~$@\e(B!
 * Article Display::             X-Face, Picons, Smileys \e$B$rI=<($9$k\e(B
                                 \e$B%/$9$k\e(B
 * Article Date::                \e$B$0$:$0$:8@$&$J!"@$3&;~$@\e(B!
 * Article Display::             X-Face, Picons, Smileys \e$B$rI=<($9$k\e(B
@@ -1371,8 +1373,8 @@ Gnus \e$B$O!"IaDL$O%0%k!<%W$,?7$7$$$+$I$&$+$r!"9XFI$7$F$$$k%0%k!<%W$H:o=|$5\e(B
 @table @code
 @item gnus-subscribe-zombies
 @vindex gnus-subscribe-zombies
 @table @code
 @item gnus-subscribe-zombies
 @vindex gnus-subscribe-zombies
-\e$B$9$Y$F$N?7$7$$%0%k!<%W$r%>%s%S\e(B (zombie) \e$B$K$7$^$9!#$3$l$,=i4|@_Dj\e(B \e$B$K$J$C\e(B
-\e$B$F$$$^$9!#8e$G%>%s%S$r\e(B (@kbd{A z} \e$B$K$h$C$F\e(B) \e$B354Q$7$?$j!"\e(B(@kbd{S z} \e$B$K$h$C\e(B
+\e$B$9$Y$F$N?7$7$$%0%k!<%W$r%>%s%S\e(B (zombie) \e$B$K$7$^$9!#$3$l$,=i4|@_Dj$K$J$C$F\e(B
+\e$B$$$^$9!#8e$G%>%s%S$r\e(B (@kbd{A z} \e$B$K$h$C$F\e(B) \e$B354Q$7$?$j!"\e(B(@kbd{S z} \e$B$K$h$C\e(B
 \e$B$F\e(B) \e$BE,@Z$KA4$F$r:o=|$7$?$j!"\e(B(@kbd{u} \e$B$K$h$C$F\e(B) \e$B9XFI$7$?$j$G$-$^$9!#\e(B
 
 @item gnus-subscribe-randomly
 \e$B$F\e(B) \e$BE,@Z$KA4$F$r:o=|$7$?$j!"\e(B(@kbd{u} \e$B$K$h$C$F\e(B) \e$B9XFI$7$?$j$G$-$^$9!#\e(B
 
 @item gnus-subscribe-randomly
@@ -1913,6 +1915,9 @@ Gnus \e$B$N5/F0$K@.8y$7$?8e$K!"0lHV:G8e$K<B9T$5$l$k%U%C%/$G$9!#\e(B
 @item R
 \e$B4{FI5-;v$N?t!#\e(B
 
 @item R
 \e$B4{FI5-;v$N?t!#\e(B
 
+@item U
+\e$B$^$@FI$^$l$?$3$H$,L5$$5-;v$N?t!#\e(B
+
 @item t
 \e$B?dDjA45-;v?t\e(B (\e$B$3$l$O<B:]$O\e(B @var{max-number} - @var{min-number} + 1)\e$B!#\e(B
 
 @item t
 \e$B?dDjA45-;v?t\e(B (\e$B$3$l$O<B:]$O\e(B @var{max-number} - @var{min-number} + 1)\e$B!#\e(B
 
@@ -2979,7 +2984,7 @@ See also @code{gnus-group-ignored-charsets-alist}.
 @end ignore
 @item posting-style
 @cindex posting-style
 @end ignore
 @item posting-style
 @cindex posting-style
-\e$B$3$N%0%k!<%W$NDI2C$NEj9FMM<0$r$3$3$N$_$KJ]B8$9$k$3$H$,$G$-$^\e(B
+\e$B$3$N%0%k!<%W$NDI2C$NEj9FMM<0$r$3$3$KJ]B8$9$k$3$H$,$G$-$^\e(B
 \e$B$9\e(B (@pxref{Posting Styles})\e$B!#=q<0$O\e(B @code{gnus-posting-style} \e$BO"A[%j%9%H\e(B
 \e$B$HF1$8$G$9$,!"$3$3$K$O%0%k!<%WL>$K9gCW$9$k@55,I=8=$O$"$j$^$;$s\e(B (\e$BEvA3$G\e(B
 \e$B$9\e(B)\e$B!#$3$N%0%k!<%W$NMM<0$NMWAG$O\e(B @code{gnus-posting-styles} \e$B$G8+$D$+$C$?\e(B
 \e$B$9\e(B (@pxref{Posting Styles})\e$B!#=q<0$O\e(B @code{gnus-posting-style} \e$BO"A[%j%9%H\e(B
 \e$B$HF1$8$G$9$,!"$3$3$K$O%0%k!<%WL>$K9gCW$9$k@55,I=8=$O$"$j$^$;$s\e(B (\e$BEvA3$G\e(B
 \e$B$9\e(B)\e$B!#$3$N%0%k!<%W$NMM<0$NMWAG$O\e(B @code{gnus-posting-styles} \e$B$G8+$D$+$C$?\e(B
@@ -2992,6 +2997,7 @@ See also @code{gnus-group-ignored-charsets-alist}.
 @example
 (posting-style
   (name "Funky Name")
 @example
 (posting-style
   (name "Funky Name")
+  ("X-My-Header" "Funky Value")
   (signature "Funky Signature"))
 @end example
 
   (signature "Funky Signature"))
 @end example
 
@@ -3528,7 +3534,7 @@ Note:
 
 \e$B$b$7$"$J$?$,$?!<$/$5$s$N%0%k!<%W$rFI$s$G$$$k$N$G$"$l$P!"%0%k!<%W$r%H%T%C\e(B
 \e$B%/Kh$K3,AXJ,$1$G$-$k$HJXMx$G$7$g$&!#\e(BEmacs \e$B$N%0%k!<%W$r$3$C$A$X!"%;%C%/%9\e(B
 
 \e$B$b$7$"$J$?$,$?!<$/$5$s$N%0%k!<%W$rFI$s$G$$$k$N$G$"$l$P!"%0%k!<%W$r%H%T%C\e(B
 \e$B%/Kh$K3,AXJ,$1$G$-$k$HJXMx$G$7$g$&!#\e(BEmacs \e$B$N%0%k!<%W$r$3$C$A$X!"%;%C%/%9\e(B
-\e$B$N%0%k!<%W$r$"$C$A$X!"$G!";D$j$r\e(B (\e$B$(\e(B? \e$B%0%k!<%W$,Fs\e(B \e$B$D$/$i$$$7$+$J$$\e(B
+\e$B$N%0%k!<%W$r$"$C$A$X!"$G!";D$j$r\e(B (\e$B$(\e(B? \e$B%0%k!<%W$,Fs$D$/$i$$$7$+$J$$\e(B
 \e$B$N\e(B?) \e$B<YKb$K$J$i$J$$$h$&$K$=$NB>$N%;%/%7%g%s$KF~$l$^$7$g$&!#$"$k$$\e(B
 \e$B$O\e(B Emacs \e$B%;%C%/%9$N%0%k!<%W$r\e(B Emacs \e$B%0%k!<%W!"%;%C%/%9%0%k!<%W$N$I$A$i$+\e(B
 \e$B$NI{%H%T%C%/$H$9$k$3$H$5$($b$G$-$^$9!=!=$"$k$$$ON>J}$K\e(B! \e$B$9$s$4$$$G$7$g$&\e(B!
 \e$B$N\e(B?) \e$B<YKb$K$J$i$J$$$h$&$K$=$NB>$N%;%/%7%g%s$KF~$l$^$7$g$&!#$"$k$$\e(B
 \e$B$O\e(B Emacs \e$B%;%C%/%9$N%0%k!<%W$r\e(B Emacs \e$B%0%k!<%W!"%;%C%/%9%0%k!<%W$N$I$A$i$+\e(B
 \e$B$NI{%H%T%C%/$H$9$k$3$H$5$($b$G$-$^$9!=!=$"$k$$$ON>J}$K\e(B! \e$B$9$s$4$$$G$7$g$&\e(B!
@@ -4200,7 +4206,7 @@ gnus \e$B$O\e(B @code{gnus-group-charter-alist} \e$B$r;H$C$F7{>O$N=j:_$rC5$7$^$9!#=
 
 @code{gnus-group-fetch-control-use-browse-url} \e$B$,Hs\e(B-@code{nil} \e$B$@$C$?$i!"\e(B
 gnus \e$B$O\e(B @code{browse-url} \e$B$r;H$C$F%3%s%H%m!<%k%a%C%;!<%8$r3+$-$^$9!#$=$&\e(B
 
 @code{gnus-group-fetch-control-use-browse-url} \e$B$,Hs\e(B-@code{nil} \e$B$@$C$?$i!"\e(B
 gnus \e$B$O\e(B @code{browse-url} \e$B$r;H$C$F%3%s%H%m!<%k%a%C%;!<%8$r3+$-$^$9!#$=$&\e(B
-\e$B$G$J$$>l9g$O\e(B @code{ange-ftp} \e$B$r;H$C$F<hF@$5$l!"0l;~%0%k!<%W\e(B \e$B$KI=<($5$l$^\e(B
+\e$B$G$J$$>l9g$O\e(B @code{ange-ftp} \e$B$r;H$C$F<hF@$5$l!"0l;~%0%k!<%W$KI=<($5$l$^\e(B
 \e$B$9!#\e(B
 
 \e$B%3%s%H%m!<%k%a%C%;!<%8$O05=L$5$l$F$$$k$3$H$KCm0U$7$F2<$5$$!#$3$N%3%^%s%I\e(B
 \e$B$9!#\e(B
 
 \e$B%3%s%H%m!<%k%a%C%;!<%8$O05=L$5$l$F$$$k$3$H$KCm0U$7$F2<$5$$!#$3$N%3%^%s%I\e(B
@@ -4985,7 +4991,10 @@ Summary Buffer} \e$B$r;2>H$7$F2<$5$$!#\e(B
 @item gnus-select-article-hook
 @vindex gnus-select-article-hook
 \e$B$3$N%U%C%/$O5-;v$,A*Br$5$l$?$H$-$K>o$K8F$P$l$^$9!#=i4|@_Dj$G$O!"A*Br$5$l\e(B
 @item gnus-select-article-hook
 @vindex gnus-select-article-hook
 \e$B$3$N%U%C%/$O5-;v$,A*Br$5$l$?$H$-$K>o$K8F$P$l$^$9!#=i4|@_Dj$G$O!"A*Br$5$l\e(B
-\e$B$?5-;v$N2<$K1#$l$F$$$k%9%l%C%I$r8+$;$k$h$&$K$J$C$F$$$^$9!#\e(B
+\e$B$?5-;v$N2<$K1#$l$F$$$k%9%l%C%I$r8+$;$k$h$&$K$J$C$F$$$^$9!#%(!<%8%'%s%H$,\e(B
+\e$B$9$Y$F$N4{FI$N5-;v$r%;!<%V$9$k$h$&$K$5$;$?$$>l9g$O!"$3$N%U%C%/\e(B
+\e$B$K\e(B @code{gnus-agent-fetch-selected-article} \e$B$rDI2C$9$k$3$H$G!"$=$l$r$9$k\e(B
+\e$B$O$:$G$9!#\e(B
 
 @item gnus-mark-article-hook
 @vindex gnus-mark-article-hook
 
 @item gnus-mark-article-hook
 @vindex gnus-mark-article-hook
@@ -5896,6 +5905,11 @@ gnus \e$B%(!<%8%'%s%H\e(B @pxref{Agent Basics} \e$B$O$$$/$D$+$N5-;v$r<+F0E*$K%@%&%s
 @subsection \e$B%W%m%;%90u$rIU$1$k\e(B
 @cindex setting process marks
 
 @subsection \e$B%W%m%;%90u$rIU$1$k\e(B
 @cindex setting process marks
 
+\e$B%W%m%;%90u$O35N,%P%C%U%!!<$K\e(B @code{#} \e$B$H$7$FI=<($5$l!"B>$N%3%^%s%I$G=hM}\e(B
+\e$B$5$;$k5-;v$K0u$rIU$1$k$?$a$K;H$o$l$^$9!#Nc$($P!";M$D$N5-;v$K$K0u$rIU$1$F\e(B
+\e$B$+$i\e(B @kbd{*} \e$B%3%^%s%I$r;H$&$H!"\e(Bgnus \e$B$O$=$l$i;M$D$N5-;v$r%-%c%C%7%e$KF~$l\e(B
+\e$B$^$9!#>\$7$/$O\e(B @pxref{Process/Prefix} \e$B$r$I$&$>!#\e(B
+
 @table @kbd
 @item M P p
 @itemx #
 @table @kbd
 @item M P p
 @itemx #
@@ -6915,8 +6929,8 @@ Gnus \e$B$O$"$J$?$,FI$`$G$"$m$&5-;v$h$j$b$?$/$5$s$N5-;v$r<hF@$7$^$9!#$3$l$O\e(B
 \e$B$=$l$r$"$J$?$N%[!<%`%G%#%l%/%H%j!<$N2<$NJL$N>l=j$K%-%c%C%7%e$9$k$N$O0UL#\e(B
 \e$B$NL5$$;v$G$9!#$"$J$?$,FsG\$NMFNL$r;H$&;v$,NI$$$H46$8$J$$8B$j$O!#\e(B
 
 \e$B$=$l$r$"$J$?$N%[!<%`%G%#%l%/%H%j!<$N2<$NJL$N>l=j$K%-%c%C%7%e$9$k$N$O0UL#\e(B
 \e$B$NL5$$;v$G$9!#$"$J$?$,FsG\$NMFNL$r;H$&;v$,NI$$$H46$8$J$$8B$j$O!#\e(B
 
-\e$B%-%c%C%7%e$r@)8B$9$k$?$a$K!"\e(B@code{gnus-cacheable-groups} \e$B$r\e(B \e$B$r%-%c%C%7%e\e(B
-\e$B$9$k%0%k!<%W$NO"A[%j%9%H!"Nc$($P\e(B @samp{^nntp} \e$B$H$9$k$+!"@55,I=\e(B
+\e$B%-%c%C%7%e$r@)8B$9$k$?$a$K!"\e(B@code{gnus-cacheable-groups} \e$B$r%-%c%C%7%e$9\e(B
+\e$B$k%0%k!<%W$NO"A[%j%9%H!"Nc$($P\e(B @samp{^nntp} \e$B$H$9$k$+!"@55,I=\e(B
 \e$B8=\e(B @code{gnus-uncacheable-groups} \e$B$rNc$($P!"\e(B@samp{^nnml} \e$B$K@_Dj$7$F2<$5\e(B
 \e$B$$!#N>J}$NJQ?t$N=i4|CM$O\e(B @code{nil} \e$B$G$9!#$b$7%0%k!<%W$,N>J}$N@55,I=8=$K\e(B
 \e$B9gCW$9$k$H!"$=$N%0%k!<%W$O%-%c%C%7%e$5$l$^$;$s!#\e(B
 \e$B8=\e(B @code{gnus-uncacheable-groups} \e$B$rNc$($P!"\e(B@samp{^nnml} \e$B$K@_Dj$7$F2<$5\e(B
 \e$B$$!#N>J}$NJQ?t$N=i4|CM$O\e(B @code{nil} \e$B$G$9!#$b$7%0%k!<%W$,N>J}$N@55,I=8=$K\e(B
 \e$B9gCW$9$k$H!"$=$N%0%k!<%W$O%-%c%C%7%e$5$l$^$;$s!#\e(B
@@ -7584,7 +7598,7 @@ Gnus \e$B$O%U%!%$%k$r1\Mw$9$k$N$r7hDj$9$k$N$K\e(B@dfn{\e$B5,B'JQ?t\e(B}\e$B$rMQ$$$^$9
 @vindex gnus-uu-save-in-digest
 @code{nil} \e$B$G$J$$$N$O!"\e(B@code{gnus-uu} \e$B$,I|9f2=$r$7$J$$$GJ]B8$r$9$k$h$&$K\e(B
 \e$B8@$o$l$?$H$-$K!"MWLs$rJ]B8$9$k$H$$$&;v$G$9!#$3$NJQ?t$,\e(B @code{nil} \e$B$G$"$k\e(B
 @vindex gnus-uu-save-in-digest
 @code{nil} \e$B$G$J$$$N$O!"\e(B@code{gnus-uu} \e$B$,I|9f2=$r$7$J$$$GJ]B8$r$9$k$h$&$K\e(B
 \e$B8@$o$l$?$H$-$K!"MWLs$rJ]B8$9$k$H$$$&;v$G$9!#$3$NJQ?t$,\e(B @code{nil} \e$B$G$"$k\e(B
-\e$B$H!"\e(B@code{gnus-uu} \e$B$O\e(B \e$B2?$b>~$j$r$7$J$$$GA4$F$r%U%!%$%k$KJ]B8$7$^$9!#MWLs\e(B
+\e$B$H!"\e(B@code{gnus-uu} \e$B$O2?$b>~$j$r$7$J$$$GA4$F$r%U%!%$%k$KJ]B8$7$^$9!#MWLs\e(B
 \e$B$O\e(B RFC1153 \e$B=`$8$F$$$^$9!=!=0UL#$N$"$kNL$r;XDj$7$F!"HV9f$rH/9T$9$k4JC1$J\e(B
 \e$BJ}K!$,8+$D$+$i$J$+$C$?$N$G!"C1=c$K$=$l$i$O@Z$jMn$H$7$F$$$^$9!#\e(B
 @end table
 \e$B$O\e(B RFC1153 \e$B=`$8$F$$$^$9!=!=0UL#$N$"$kNL$r;XDj$7$F!"HV9f$rH/9T$9$k4JC1$J\e(B
 \e$BJ}K!$,8+$D$+$i$J$+$C$?$N$G!"C1=c$K$=$l$i$O@Z$jMn$H$7$F$$$^$9!#\e(B
 @end table
@@ -7682,7 +7696,7 @@ Gnus \e$B$O%U%!%$%k$r1\Mw$9$k$N$r7hDj$9$k$N$K\e(B@dfn{\e$B5,B'JQ?t\e(B}\e$B$rMQ$$$^$9
 * Article Washing::             \e$B?M@8$r$b$C$H$h$/$9$k$?$/$5$s$N5$$NMx$$$?\e(B
                                 \e$B4X?t\e(B
 * Article Header::              \e$B%X%C%@!<$r$$$m$$$mJQ7A$5$;$k\e(B
 * Article Washing::             \e$B?M@8$r$b$C$H$h$/$9$k$?$/$5$s$N5$$NMx$$$?\e(B
                                 \e$B4X?t\e(B
 * Article Header::              \e$B%X%C%@!<$r$$$m$$$mJQ7A$5$;$k\e(B
-* Article Buttons::             URL \e$B$d\e(B Message-ID \e$B$d\e(B \e$B%"%I%l%9$J$I$r%/%j%C\e(B
+* Article Buttons::             URL \e$B$d\e(B Message-ID \e$B$d%"%I%l%9$J$I$r%/%j%C\e(B
                                 \e$B%/$9$k\e(B
 * Article Date::                \e$B$0$:$0$:8@$&$J!"@$3&;~$@\e(B!
 * Article Display::             X-Face, Picons, Smileys \e$B$rI=<($9$k\e(B
                                 \e$B%/$9$k\e(B
 * Article Date::                \e$B$0$:$0$:8@$&$J!"@$3&;~$@\e(B!
 * Article Display::             X-Face, Picons, Smileys \e$B$rI=<($9$k\e(B
@@ -7791,7 +7805,7 @@ Fonts})\e$B!#F1$8%a%C%;!<%8$NCf$KJ#?t$N5-;v$+$i$N0zMQ$,$"$k$H!"\e(Bgnus \e$B$O$=$l$
 @cindex gnus-article-emphasize
 @kindex W e (\e$B35N,\e(B)
 \e$B?M!9$O$h$/%K%e!<%9$N5-;v$G\e(B @samp{_\e$B$3$l\e(B_} \e$B$d\e(B @samp{*\e$B$3$l\e(B*} \e$B$^$?\e(B
 @cindex gnus-article-emphasize
 @kindex W e (\e$B35N,\e(B)
 \e$B?M!9$O$h$/%K%e!<%9$N5-;v$G\e(B @samp{_\e$B$3$l\e(B_} \e$B$d\e(B @samp{*\e$B$3$l\e(B*} \e$B$^$?\e(B
-\e$B$O\e(B @samp{/\e$B$3$l\e(B/} \e$B$N$h$&$J$b$N$r;H$C$FC18l$r6/D4$7$^$9!#\e(BGnus \e$B$O\e(B \e$B5-;v$rL?\e(B
+\e$B$O\e(B @samp{/\e$B$3$l\e(B/} \e$B$N$h$&$J$b$N$r;H$C$FC18l$r6/D4$7$^$9!#\e(BGnus \e$B$O5-;v$rL?\e(B
 \e$BNa\e(B @kbd{W e} (@code{gnus-article-emphasize}) \e$B$K$+$1$k;v$K$h$C$FAGE($K8+\e(B
 \e$B$($k$h$&$K$G$-$^$9!#\e(B
 
 \e$BNa\e(B @kbd{W e} (@code{gnus-article-emphasize}) \e$B$K$+$1$k;v$K$h$C$FAGE($K8+\e(B
 \e$B$($k$h$&$K$G$-$^$9!#\e(B
 
@@ -8116,7 +8130,7 @@ gnus \e$B$,5-;v$rI=<($9$k4{Dj$N$d$jJ}$rJQ$($?$$$H$-\e(B
 @cindex M****s*** sm*rtq**t*s
 @cindex Latin 1
 @code{gnus-article-dumbquotes-map} \e$B$K1~$8$F!"%^"#"#"#%="#\e(B
 @cindex M****s*** sm*rtq**t*s
 @cindex Latin 1
 @code{gnus-article-dumbquotes-map} \e$B$K1~$8$F!"%^"#"#"#%="#\e(B
-\e$B"#\e(B sm*rtq**t*s \e$B$r=hM}$7$^$9\e(B \e$B$3$N4X?t$OJ8;z$,\e(B sm*rtq**t* \e$B$+$I$&$+$r?dB,$7\e(B
+\e$B"#\e(B sm*rtq**t*s \e$B$r=hM}$7$^$9!#$3$N4X?t$OJ8;z$,\e(B sm*rtq**t* \e$B$+$I$&$+$r?dB,$7\e(B
 \e$B$^$9$N$G!"BPOCE*$K$N$_;HMQ$5$l$k$Y$-$G$"$k$3$H$KCm0U$7$F$/$@$5$$!#\e(B
 
 Sm*rtq**t*s \e$B$O$b$C$HB?$/$N0zMQJ8;z$rDs6!$9$k$?$a$K!"%^"#"#"#%="#"#$,>!<j\e(B
 \e$B$^$9$N$G!"BPOCE*$K$N$_;HMQ$5$l$k$Y$-$G$"$k$3$H$KCm0U$7$F$/$@$5$$!#\e(B
 
 Sm*rtq**t*s \e$B$O$b$C$HB?$/$N0zMQJ8;z$rDs6!$9$k$?$a$K!"%^"#"#"#%="#"#$,>!<j\e(B
@@ -8126,11 +8140,34 @@ Sm*rtq**t*s \e$B$O$b$C$HB?$/$N0zMQJ8;z$rDs6!$9$k$?$a$K!"%^"#"#"#%="#"#$,>!<j\e(B
 
 @item W k
 @kindex W k (\e$B35N,\e(B)
 
 @item W k
 @kindex W k (\e$B35N,\e(B)
+@kindex W Y f (\e$B35N,\e(B)
 @findex gnus-article-outlook-deuglify-article
 @cindex Outlook Express
 @findex gnus-article-outlook-deuglify-article
 @cindex Outlook Express
-\e$B2u$l$?\e(B Outlook (Express) \e$B$N5-;v$r\e(B deuglify \e$B$7$F:FI=<($7$^\e(B
+\e$B2u$l$?\e(B Outlook (Express) \e$B$N5-;v$r\e(B deuglify \e$B$7$^\e(B
 \e$B$9\e(B (@code{gnus-article-outlook-deuglify-article})\e$B!#\e(B
 
 \e$B$9\e(B (@code{gnus-article-outlook-deuglify-article})\e$B!#\e(B
 
+@item W Y u
+@kindex W Y u (\e$B35N,\e(B)
+@findex gnus-outlook-unwrap-lines
+\e$B@^$jJV$5$l$?0zMQ9T$N$h$&$K8+$($k9T$N@^$jJV$7$r2r$-$^$9!#@^$jJV$7$,2r$+$l\e(B
+\e$B$?9T$N:G>.$*$h$S:GBg$ND9$5$rI=\e(B
+\e$B$9\e(B @code{gnus-outlook-deuglify-unwrap-min} \e$B$*$h\e(B
+\e$B$S\e(B @code{gnus-outlook-deuglify-unwrap-max} \e$B$rD4@0$9$k$3$H$K$h$C$F!"$I$N\e(B
+\e$B9T$N@^$jJV$7$,2r$+$l$k$+$r@)8f$9$k$3$H$,$G$-$^$9!#\e(B
+(@code{gnus-outlook-deuglify-article})\e$B!#\e(B
+
+@item W Y a
+@kindex W Y a (\e$B35N,\e(B)
+@findex gnus-outlook-repair-attribution
+\e$B2u$l$?B0@-9T$r=$I|$7$^$9!#\e(B
+(@code{gnus-outlook-repair-attribution})\e$B!#\e(B
+
+@item W Y c
+@kindex W Y c (\e$B35N,\e(B)
+@findex gnus-outlook-rearrange-citation
+\e$B2u$l$?0zMQ$r!"%F%-%9%H$rJB$YD>$9$3$H$K$h$C$F=$I|$7$^$9!#\e(B
+(@code{gnus-outlook-rearrange-citation})\e$B!#\e(B
+
 @item W w
 @kindex W w (\e$B35N,\e(B)
 @findex gnus-article-fill-cited-article
 @item W w
 @kindex W w (\e$B35N,\e(B)
 @findex gnus-article-fill-cited-article
@@ -8205,10 +8242,10 @@ URL \e$B$K4^$^$l$k2~9T$r:o=|$7$^$9!#$$$/$D$+$N%a%$%i!<$O!"9T$rC;$/$9$k$?$a$K\e(B
 \e$B@\F,<-$,M?$($i$l$k$H!"2?$NJ8;z=89g\e(B (charset) \e$B$H$7$F07$&$+$r?R$M$i$l$^$9!#\e(B
 
 @vindex gnus-article-wash-function
 \e$B@\F,<-$,M?$($i$l$k$H!"2?$NJ8;z=89g\e(B (charset) \e$B$H$7$F07$&$+$r?R$M$i$l$^$9!#\e(B
 
 @vindex gnus-article-wash-function
-\e$B%G%#%U%)%k%H$G$O\e(B @sc{html} \e$B$NJQ49$K\e(B @code{mm-inline-text-html-renderer}
-(@pxref{Customization, , , emacs-mime}) \e$B$G@_Dj$5$l$?4X?t$r;H$$$^$9$,!"$3\e(B
-\e$B$l$OJQ?t\e(B @code{gnus-article-wash-function} \e$B$G@)8f$5$l$^$9!#;H$&$3$H$,$G\e(B
-\e$B$-$k!"$"$i$+$8$aMQ0U$5$l$?4X?t$O0J2<$NDL$j$G$9!#\e(B
+\e$B%G%#%U%)%k%H$G$O\e(B @sc{html} \e$B$NJQ49$K\e(B @code{mm-text-html-renderer}
+(@pxref{(emacs-mime)Display Customization}) \e$B$G@_Dj$5$l$?4X?t$r;H$$$^$9$,!"\e(B
+\e$B$3$l$OJQ?t\e(B @code{gnus-article-wash-function} \e$B$G@)8f$5$l$^$9!#;H$&$3$H$,\e(B
+\e$B$G$-$k!"$"$i$+$8$aMQ0U$5$l$?4X?t$O0J2<$NDL$j$G$9!#\e(B
 
 @table @code
 @item w3
 
 @table @code
 @item w3
@@ -9401,7 +9438,7 @@ Gnus \e$B$N\e(B info \e$B$N@a\e(B (node) \e$B$K0\F0$7$^$9\e(B (@code{gnus-info-find-no
 @findex gnus-summary-read-document
 \e$B$3$NL?Na$O>e$N$b$N$KHs>o$K;w$F$$$^$9$,!"$$$/$D$+$NJ8=q$r0l$D$NBg!<$-$$%0\e(B
 \e$B%k!<%W$K=8$a$^$9\e(B (@code{gnus-summary-read-read-document})\e$B!#$=$l$O$$$/$D\e(B
 @findex gnus-summary-read-document
 \e$B$3$NL?Na$O>e$N$b$N$KHs>o$K;w$F$$$^$9$,!"$$$/$D$+$NJ8=q$r0l$D$NBg!<$-$$%0\e(B
 \e$B%k!<%W$K=8$a$^$9\e(B (@code{gnus-summary-read-read-document})\e$B!#$=$l$O$$$/$D\e(B
-\e$B$+$N\e(B @code{nndoc} \e$B%0%k!<%W$r$=$l$>$l$NJ8=q$N$?$a$K\e(B \e$B3+$-!"$=$l$+$i$3$l$i\e(B
+\e$B$+$N\e(B @code{nndoc} \e$B%0%k!<%W$r$=$l$>$l$NJ8=q$N$?$a$K3+$-!"$=$l$+$i$3$l$i\e(B
 \e$B$N\e(B @code{nndoc} \e$B%0%k!<%W$N>e$K\e(B @code{nnvirtual} \e$B%0%k!<%W$r3+$/;v$K$h$C$F\e(B
 \e$B$3$N;v$r2DG=$K$7$F$$$^$9!#$3$NL?Na$O%W%m%;%9\e(B/\e$B@\F,0z?t$N=,47$rM}2r$7$^\e(B
 \e$B$9\e(B (@pxref{Process/Prefix})\e$B!#\e(B
 \e$B$N\e(B @code{nndoc} \e$B%0%k!<%W$N>e$K\e(B @code{nnvirtual} \e$B%0%k!<%W$r3+$/;v$K$h$C$F\e(B
 \e$B$3$N;v$r2DG=$K$7$F$$$^$9!#$3$NL?Na$O%W%m%;%9\e(B/\e$B@\F,0z?t$N=,47$rM}2r$7$^\e(B
 \e$B$9\e(B (@pxref{Process/Prefix})\e$B!#\e(B
@@ -9583,9 +9620,9 @@ Parameters}) \e$B$rJT=8$7$^$9\e(B (@code{gnus-summary-edit-parameters})\e$B!#\e(B
 \e$B$O$=$l$OB.EY$r$H$F$bB.$/$9$k$+$i$G$9\e(B) \e$B$N;HMQ2DG=$J\e(B @sc{nntp} \e$B%5!<%P!<$r\e(B
 \e$B;H$C$F$$$k$3$H$G$9!#$3$l$O320-$J$N$G$9$,!"$"$!!"Ha$7$$$+$J!"Hs>o$KNI$/$"\e(B
 \e$B$k;v$G$9!#\e(BGnus \e$B$O$"$J$?$,FI$s$@A4$F$N5-;v$K\e(B @code{Xref} \e$B9T$rEPO?$9$k;v$G!"\e(B
 \e$B$O$=$l$OB.EY$r$H$F$bB.$/$9$k$+$i$G$9\e(B) \e$B$N;HMQ2DG=$J\e(B @sc{nntp} \e$B%5!<%P!<$r\e(B
 \e$B;H$C$F$$$k$3$H$G$9!#$3$l$O320-$J$N$G$9$,!"$"$!!"Ha$7$$$+$J!"Hs>o$KNI$/$"\e(B
 \e$B$k;v$G$9!#\e(BGnus \e$B$O$"$J$?$,FI$s$@A4$F$N5-;v$K\e(B @code{Xref} \e$B9T$rEPO?$9$k;v$G!"\e(B
-\e$B@5$7$$;v$r$7$h$&\e(B \e$B$H$7$^$9$,!"5-;v$r:o=|$9$k$+!"FI$^$J$$$G4{FI$N0u$rIU$1\e(B
-\e$B$k$H!"\e(Bgnus \e$B$O$3$l$i$N5-;v$K\e(B @code{Xref} \e$B$N9T$r$N$>$-$^$o$k5!2q$rF@$k;v$,\e(B
-\e$BL5$/!"Aj8_;2>H5!9=$rMQ$$$k;v$,$G$-$^$;$s!#\e(B
+\e$B@5$7$$;v$r$7$h$&$H$7$^$9$,!"5-;v$r:o=|$9$k$+!"FI$^$J$$$G4{FI$N0u$rIU$1$k\e(B
+\e$B$H!"\e(Bgnus \e$B$O$3$l$i$N5-;v$K\e(B @code{Xref} \e$B$N9T$r$N$>$-$^$o$k5!2q$rF@$k;v$,L5\e(B
+\e$B$/!"Aj8_;2>H5!9=$rMQ$$$k;v$,$G$-$^$;$s!#\e(B
 
 @cindex LIST overview.fmt
 @cindex overview.fmt
 
 @cindex LIST overview.fmt
 @cindex overview.fmt
@@ -9646,7 +9683,7 @@ Gnus \e$B$K$$$D$G$b@5$7$$\e(B @code{Xref} \e$B$r<hF@$9$k$h$&$K$5$;$?$$$N$G$"$l$P!"\e
 
 \e$B=EJ#M^@)$O$"$^$jA!:Y$J$b$N$G$O$"$j$^$;$s!#$I$A$i$+$H$$$&$H!"BgDH$N$h$&$J\e(B
 \e$B$b$N$G$9!#$=$l$OHs>o$KC1=c$JJ}K!$GF0:n$7$F$$$^$9!=!=$b$75-;v$K4{FI$N0u$r\e(B
 
 \e$B=EJ#M^@)$O$"$^$jA!:Y$J$b$N$G$O$"$j$^$;$s!#$I$A$i$+$H$$$&$H!"BgDH$N$h$&$J\e(B
 \e$B$b$N$G$9!#$=$l$OHs>o$KC1=c$JJ}K!$GF0:n$7$F$$$^$9!=!=$b$75-;v$K4{FI$N0u$r\e(B
-\e$BIU$1$l$P!"$=$l$O$3$N\e(B Message-ID \e$B$r\e(B \e$B%-%c%C%7%e$K2C$($^$9!#<!$K$3\e(B
+\e$BIU$1$l$P!"$=$l$O$3$N\e(B Message-ID \e$B$r%-%c%C%7%e$K2C$($^$9!#<!$K$3\e(B
 \e$B$N\e(B Message-ID \e$B$K$G$"$C$?$H$-$O!"\e(B@samp{M} \e$B0u$K$h$C$F5-;v$K4{FI$N0u$rIU$1\e(B
 \e$B$^$9!#$=$l$O$=$N5-;v$,$I$N%0%k!<%W$K$"$k$+$O5$$K$7$^$;$s!#\e(B
 
 \e$B$N\e(B Message-ID \e$B$K$G$"$C$?$H$-$O!"\e(B@samp{M} \e$B0u$K$h$C$F5-;v$K4{FI$N0u$rIU$1\e(B
 \e$B$^$9!#$=$l$O$=$N5-;v$,$I$N%0%k!<%W$K$"$k$+$O5$$K$7$^$;$s!#\e(B
 
@@ -10406,7 +10443,7 @@ ISP \e$B$,\e(B POP-before-SMTP \e$B$NG'>Z$rMW5a$7$F$$$k>l9g$KM-MQ$G$9!#4X\e(B
 \e$B$b$7$"$J$?$N%K%e!<%9%5!<%P!<$,K\Ev$K%a!<%j%s%0%j%9%H$+$i\e(B @sc{nntp} \e$B%5!<\e(B
 \e$B%P!<$X$N%2!<%H%&%'%$$rDs6!$7$F$$$k$N$G$"$l$P!"$=$l$i$N%0%k!<%W$OLdBj$J$/\e(B
 \e$BFI$a$k$G$7$g$&!#$7$+$74JC1$K$O$=$l$i$KEj9F\e(B/\e$B%U%)%m!<%"%C%W$9$k$3$H$O$G$-\e(B
 \e$B$b$7$"$J$?$N%K%e!<%9%5!<%P!<$,K\Ev$K%a!<%j%s%0%j%9%H$+$i\e(B @sc{nntp} \e$B%5!<\e(B
 \e$B%P!<$X$N%2!<%H%&%'%$$rDs6!$7$F$$$k$N$G$"$l$P!"$=$l$i$N%0%k!<%W$OLdBj$J$/\e(B
 \e$BFI$a$k$G$7$g$&!#$7$+$74JC1$K$O$=$l$i$KEj9F\e(B/\e$B%U%)%m!<%"%C%W$9$k$3$H$O$G$-\e(B
-\e$B$^$;$s!#0l$D$N2r7hK!$O\e(B \e$B%0%k!<%W%Q%i%a!<\e(B
+\e$B$^$;$s!#0l$D$N2r7hK!$O%0%k!<%W%Q%i%a!<\e(B
 \e$B%?\e(B (@pxref{Group Parameters}) \e$B$K\e(B @code{to-address} \e$B$r2C$($k;v$G$9!#4JC1\e(B
 \e$B$K$G$-$k$N$O!"\e(B@code{gnus-mailing-list-groups} \e$B$r!"K\Ev$K%a!<%j%s%0%j%9%H\e(B
 \e$B$G$"$k$h$&$J%0%k!<%W$K9gCW$9$k@55,I=8=$K@_Dj$9$k$3$H$G$9!#$=$N8e$O!"$9$/\e(B
 \e$B%?\e(B (@pxref{Group Parameters}) \e$B$K\e(B @code{to-address} \e$B$r2C$($k;v$G$9!#4JC1\e(B
 \e$B$K$G$-$k$N$O!"\e(B@code{gnus-mailing-list-groups} \e$B$r!"K\Ev$K%a!<%j%s%0%j%9%H\e(B
 \e$B$G$"$k$h$&$J%0%k!<%W$K9gCW$9$k@55,I=8=$K@_Dj$9$k$3$H$G$9!#$=$N8e$O!"$9$/\e(B
@@ -10761,7 +10798,7 @@ from date id references chars lines xref extra \e$B$N3F%X%C%@!<$+$i@.$k%Y%/\e(B
 
 @cindex nndraft
 @vindex nndraft-directory
 
 @cindex nndraft
 @vindex nndraft-directory
-\e$B2<=q$-%0%k!<%W$O\e(B @samp{nndraft:drafts} \e$B$H8F$P$l$kFCJL$J%0%k!<%W\e(B \e$B$G$9\e(B (\e$B$b\e(B
+\e$B2<=q$-%0%k!<%W$O\e(B @samp{nndraft:drafts} \e$B$H8F$P$l$kFCJL$J%0%k!<%W$G$9\e(B (\e$B$b\e(B
 \e$B$7$"$J$?$,A4$F$rCN$i$J$1$l$P$J$i$J$$$N$G$"$l$P!"$=$l$O\e(B @code{nndraft} \e$B%0\e(B
 \e$B%k!<%W$H$7$F<BAu$5$l$F$$$^$9\e(B)\e$B!#JQ?t\e(B @code{nndraft-directory} \e$B$O$=$N%U%!\e(B
 \e$B%$%k$r\e(B @code{nndraft} \e$B$,$I$3$KJ]4I$9$k$Y$-$+$r;XDj$7$^$9!#$3$N%0%k!<%W$,\e(B
 \e$B$7$"$J$?$,A4$F$rCN$i$J$1$l$P$J$i$J$$$N$G$"$l$P!"$=$l$O\e(B @code{nndraft} \e$B%0\e(B
 \e$B%k!<%W$H$7$F<BAu$5$l$F$$$^$9\e(B)\e$B!#JQ?t\e(B @code{nndraft-directory} \e$B$O$=$N%U%!\e(B
 \e$B%$%k$r\e(B @code{nndraft} \e$B$,$I$3$KJ]4I$9$k$Y$-$+$r;XDj$7$^$9!#$3$N%0%k!<%W$,\e(B
@@ -11956,7 +11993,8 @@ Gnus \e$B$r;H$C$F?7$7$$%a!<%k$rFI$`;v$OHs>o$K4JC1$G$9!#$"$J$?$N%a!<%k%P%C%/\e(B
 \e$B$1$G!"$"$H$N$3$H$O<+F0E*$K5/$3$j$^$9!#\e(B
 
 \e$BNc$($P!"\e(B@code{nnml} (\e$B$3$l$O\e(B "\e$B0l%a!<%k0l%U%!%$%k\e(B" \e$B%P%C%/%(%s%I$G$9\e(B) \e$B$r;H\e(B
 \e$B$1$G!"$"$H$N$3$H$O<+F0E*$K5/$3$j$^$9!#\e(B
 
 \e$BNc$($P!"\e(B@code{nnml} (\e$B$3$l$O\e(B "\e$B0l%a!<%k0l%U%!%$%k\e(B" \e$B%P%C%/%(%s%I$G$9\e(B) \e$B$r;H\e(B
-\e$B$$$?$$$J$i!"<!$N$b$N$r$"$J$?$N\e(B @file{.gnus} \e$B%U%!%$%k$KF~$l$k;v$,$G$-$^$9!#\e(B
+\e$B$$$?$$$J$i!"<!$N$b$N$r$"$J$?$N\e(B @file{.gnus.el} \e$B%U%!%$%k$KF~$l$k;v$,$G$-\e(B
+\e$B$^$9!#\e(B
 
 @lisp
 (setq gnus-secondary-select-methods '((nnml "")))
 
 @lisp
 (setq gnus-secondary-select-methods '((nnml "")))
@@ -12841,13 +12879,13 @@ table) \e$B$K=>$C$F40A4$K9gCW$7$J$1$l$P$J$j$^$;$s!#@55,I=8=$G%U%#!<%k%IL>$+\e(B
 @findex nnmail-split-fancy-with-parent
 \e$B4X?t\e(B @code{nnmail-split-fancy-with-parent} \e$B$O!"%U%)%m!<%"%C%W5-;v$r?F5-\e(B
 \e$B;v$HF1$8%0%k!<%W$K?6$jJ,$1$k$?$a$K;H$$$^$9!#%a!<%k$N?6$jJ,$1$r0l@87|L?@_\e(B
 @findex nnmail-split-fancy-with-parent
 \e$B4X?t\e(B @code{nnmail-split-fancy-with-parent} \e$B$O!"%U%)%m!<%"%C%W5-;v$r?F5-\e(B
 \e$B;v$HF1$8%0%k!<%W$K?6$jJ,$1$k$?$a$K;H$$$^$9!#%a!<%k$N?6$jJ,$1$r0l@87|L?@_\e(B
-\e$BDj$7$F$_$F$b40`z$K$O$G$-$J$$$3$H$,$"$j$^$9$M!#\e(B \e$BNc$($P!">e;J$+$i8D?M08$F\e(B
-\e$B$N%a!<%k$,FO$$$?$H$7$^$9!#<+J,$,7H$C$F$$$k%W%m%8%'%/%H$H$OJL$NOC$G$9!#$1\e(B
-\e$B$l$I!VB>$N%a!<%k$H6hJL$G$-$k$h$&$K$3$l$3$l$3$&$$$&8@MU$rI=Bj$K=q$$$F$/$@\e(B
-\e$B$5$$!W$H>e;J$K8~$+$C$F;X?^$9$k$o$1$K$O$$$-$^$;$s$+$i!"7k6I<+J,$N<j$rHQ$o\e(B
-\e$B$7$F$R$H$D$R$H$D%a!<%k$r@5$7$$%0%k!<%W$K?6$jJ,$1$k$O$a$K$J$j$^$9!#$=$s$J\e(B
-\e$B$H$-$K$3$N4X?t$r;H$&$H!"$3$NLLE]$J:n6H$r\e(B 1 \e$B%9%l%C%I$K$D$-\e(B 1 \e$B2s$-$j$G:Q$^\e(B
-\e$B$9$3$H$,$G$-$^$9!#\e(B
+\e$BDj$7$F$_$F$b40`z$K$O$G$-$J$$$3$H$,$"$j$^$9$M!#Nc$($P!">e;J$+$i8D?M08$F$N\e(B
+\e$B%a!<%k$,FO$$$?$H$7$^$9!#<+J,$,7H$C$F$$$k%W%m%8%'%/%H$H$OJL$NOC$G$9!#$1$l\e(B
+\e$B$I!VB>$N%a!<%k$H6hJL$G$-$k$h$&$K$3$l$3$l$3$&$$$&8@MU$rI=Bj$K=q$$$F$/$@$5\e(B
+\e$B$$!W$H>e;J$K8~$+$C$F;X?^$9$k$o$1$K$O$$$-$^$;$s$+$i!"7k6I<+J,$N<j$rHQ$o$7\e(B
+\e$B$F$R$H$D$R$H$D%a!<%k$r@5$7$$%0%k!<%W$K?6$jJ,$1$k$O$a$K$J$j$^$9!#$=$s$J$H\e(B
+\e$B$-$K$3$N4X?t$r;H$&$H!"$3$NLLE]$J:n6H$r0l%9%l%C%I$K$D$-0l2s$-$j$G:Q$^$9$3\e(B
+\e$B$H$,$G$-$^$9!#\e(B
 
 \e$B$3$N5!G=$rMxMQ$9$k$?$a$K$O!"$^$:JQ\e(B
 \e$B?t\e(B @code{nnmail-treat-duplicates} \e$B$H\e(B @code{nnmail-cache-accepted-message-ids} \e$B$N\e(B
 
 \e$B$3$N5!G=$rMxMQ$9$k$?$a$K$O!"$^$:JQ\e(B
 \e$B?t\e(B @code{nnmail-treat-duplicates} \e$B$H\e(B @code{nnmail-cache-accepted-message-ids} \e$B$N\e(B
@@ -12865,7 +12903,7 @@ table) \e$B$K=>$C$F40A4$K9gCW$7$J$1$l$P$J$j$^$;$s!#@55,I=8=$G%U%#!<%k%IL>$+\e(B
 
 \e$B$3$N5!G=$O<B:]!"<!$NMM$KF/$$$F$$$^$9\e(B: \e$BJQ?t\e(B
 @code{nnmail-treat-duplicates} \e$B$NCM$,Hs\e(B-nil \e$B$N>l9g!"\e(BGnus \e$B$O8+$D$1$?A45-\e(B
 
 \e$B$3$N5!G=$O<B:]!"<!$NMM$KF/$$$F$$$^$9\e(B: \e$BJQ?t\e(B
 @code{nnmail-treat-duplicates} \e$B$NCM$,Hs\e(B-nil \e$B$N>l9g!"\e(BGnus \e$B$O8+$D$1$?A45-\e(B
-\e$B;v$N%a%C%;!<%8\e(B ID \e$B$r\e(B \e$BJQ?t\e(B @code{nnmail-message-id-cache-file} \e$B$,;XDj$9$k\e(B
+\e$B;v$N%a%C%;!<%8\e(B ID \e$B$rJQ?t\e(B @code{nnmail-message-id-cache-file} \e$B$,;XDj$9$k\e(B
 \e$B%U%!%$%k$K5-O?$7$^$9!#$3$N$H$-!"$=$l$>$l$N5-;v$,B8:_$9$k%0%k!<%W$NL>A0$r\e(B
 \e$BJ;5-$7$^$9\e(B (\e$B$?$@$7%a!<%k$N>l9g$@$1!"$5$b$J$1$l$P%0%k!<%WL>$OD4$Y$^$;$s\e(B)\e$B!#\e(B
 \e$B$5$F!"$$$h$$$h%a!<%k$N?6$jJ,$1$,;O$^$k$H!"4X?t\e(B
 \e$B%U%!%$%k$K5-O?$7$^$9!#$3$N$H$-!"$=$l$>$l$N5-;v$,B8:_$9$k%0%k!<%W$NL>A0$r\e(B
 \e$BJ;5-$7$^$9\e(B (\e$B$?$@$7%a!<%k$N>l9g$@$1!"$5$b$J$1$l$P%0%k!<%WL>$OD4$Y$^$;$s\e(B)\e$B!#\e(B
 \e$B$5$F!"$$$h$$$h%a!<%k$N?6$jJ,$1$,;O$^$k$H!"4X?t\e(B
@@ -13005,7 +13043,7 @@ nnml:mail.others:
 \e$B99?7$7$J$1$l$P$J$j$^$;$s!#\e(B@code{gnus-group-split-update} \e$B$r<B9T$9$k$3$H\e(B
 \e$B$G$=$l$r9T$($^$9!#<+F0E*$K99?7$5$l$kJ}$,9%$_$J$i!"\e(B
 @code{gnus-group-split-setup} \e$B$K$=$l$r<B9T$9$k$h$&$K65$($k$@$1$G$9!#Nc$(\e(B
 \e$B99?7$7$J$1$l$P$J$j$^$;$s!#\e(B@code{gnus-group-split-update} \e$B$r<B9T$9$k$3$H\e(B
 \e$B$G$=$l$r9T$($^$9!#<+F0E*$K99?7$5$l$kJ}$,9%$_$J$i!"\e(B
 @code{gnus-group-split-setup} \e$B$K$=$l$r<B9T$9$k$h$&$K65$($k$@$1$G$9!#Nc$(\e(B
-\e$B$P!"\e(B@file{.gnus} \e$B$K0J2<$N$b$N$rDI2C$7$F$/$@$5$$\e(B:
+\e$B$P!"\e(B@file{.gnus.el} \e$B$K0J2<$N$b$N$rDI2C$7$F$/$@$5$$\e(B:
 
 @lisp
 (gnus-group-split-setup AUTO-UPDATE CATCH-ALL)
 
 @lisp
 (gnus-group-split-setup AUTO-UPDATE CATCH-ALL)
@@ -13128,8 +13166,8 @@ total-expire \e$B$NMxE@$O!"E,1~%9%3%"IU$1\e(B @pxref{Adaptive Scoring} \e$B$GNI9%$K
 \e$B%G%#%U%)%k%H$G$O<+F04|8B@Z$l>C5n2DG=$r;HMQ$9$k$H!"\e(Bgnus \e$B$O$"$J$?$,FI$s$@\e(B
 \e$BA4$F$N5-;v$r!"$=$l$,4{FI$G$"$C$?$+L$FI$G$"$C$?$+$K4X$o$i$:!"4|8B@Z$l>C5n\e(B
 \e$B2DG=$H$7$F0u$rIU$1$^$9!#4{FI$N0u$NIU$$$?5-;v$,<+F0E*$K4|8B@Z$l>C5n2DG=$H\e(B
 \e$B%G%#%U%)%k%H$G$O<+F04|8B@Z$l>C5n2DG=$r;HMQ$9$k$H!"\e(Bgnus \e$B$O$"$J$?$,FI$s$@\e(B
 \e$BA4$F$N5-;v$r!"$=$l$,4{FI$G$"$C$?$+L$FI$G$"$C$?$+$K4X$o$i$:!"4|8B@Z$l>C5n\e(B
 \e$B2DG=$H$7$F0u$rIU$1$^$9!#4{FI$N0u$NIU$$$?5-;v$,<+F0E*$K4|8B@Z$l>C5n2DG=$H\e(B
-\e$B$7$F0uIU$1$i$l$k$N$rHr$1$k$?$a$K!"0J2<$N$h$&$J$b$N$r\e(B @file{.gnus} \e$B%U%!%$\e(B
-\e$B%k$K=q$/;v$,$G$-$^$9\e(B:
+\e$B$7$F0uIU$1$i$l$k$N$rHr$1$k$?$a$K!"0J2<$N$h$&$J$b$N$r\e(B @file{.gnus.el} \e$B%U%!\e(B
+\e$B%$%k$K=q$/;v$,$G$-$^$9\e(B:
 
 @vindex gnus-mark-article-hook
 @lisp
 
 @vindex gnus-mark-article-hook
 @lisp
@@ -15906,11 +15944,11 @@ nnvirtual \e$B%0%k!<%W\e(B (@dfn{nnvirtual group}) \e$B$O<B$OB>$N%0%k!<%W$N=89g0J>e
 @code{nnvirtual} \e$B$O2>A[%0%k!<%W$KF~$C$?$H$->o$K!"L$FI5-;v$rAv::$7$^$9!#\e(B
 \e$B$3$NJQ?t$,\e(B @code{nil} (\e$B$3$l$,=i4|@_Dj\e(B)\e$B$G$"$C$F!"2>A[%0%k!<%W$r:n@.$7$?8e\e(B
 \e$B$K9=@.%0%k!<%WFb$N5-;v$rFI$s$@>l9g$O!"$=$N9=@.%0%k!<%W$GFI$^$l$?5-;v$O!"\e(B
 @code{nnvirtual} \e$B$O2>A[%0%k!<%W$KF~$C$?$H$->o$K!"L$FI5-;v$rAv::$7$^$9!#\e(B
 \e$B$3$NJQ?t$,\e(B @code{nil} (\e$B$3$l$,=i4|@_Dj\e(B)\e$B$G$"$C$F!"2>A[%0%k!<%W$r:n@.$7$?8e\e(B
 \e$B$K9=@.%0%k!<%WFb$N5-;v$rFI$s$@>l9g$O!"$=$N9=@.%0%k!<%W$GFI$^$l$?5-;v$O!"\e(B
-\e$B2>A[%0%k!<%W$KF~$C$?$H$-$KI=<($5$l\e(B \e$B$k$G$7$g$&!#$b$76&DL$N9=@.%0%k!<%W$r\e(B
-\e$B;}$DFs$D$N2>A[%0%k!<%W$,$"$k>l9g$K$b$3$N1F6A$,$"$j$^$9!#$=$N>l9g$O$3$NJQ\e(B
-\e$B?t$r\e(B @code{t} \e$B$K$7$?J}$,NI$$$G$9!#$"$k$$$O2>A[%0%k!<%W$KF~$k;~$K!"Kh2s$=\e(B
-\e$B$N%0%k!<%W$N>e$G\e(B @code{M-g} \e$B$rC!$$$F$bNI$$$G$9\e(B --- \e$B$3$l$O$[$\F1MM$N8z2L\e(B
-\e$B$,$"$j$^$9!#\e(B
+\e$B2>A[%0%k!<%W$KF~$C$?$H$-$KI=<($5$l$k$G$7$g$&!#$b$76&DL$N9=@.%0%k!<%W$r;}\e(B
+\e$B$DFs$D$N2>A[%0%k!<%W$,$"$k>l9g$K$b$3$N1F6A$,$"$j$^$9!#$=$N>l9g$O$3$NJQ?t\e(B
+\e$B$r\e(B @code{t} \e$B$K$7$?J}$,NI$$$G$9!#$"$k$$$O2>A[%0%k!<%W$KF~$k;~$K!"Kh2s$=$N\e(B
+\e$B%0%k!<%W$N>e$G\e(B @code{M-g} \e$B$rC!$$$F$bNI$$$G$9\e(B --- \e$B$3$l$O$[$\F1MM$N8z2L$,\e(B
+\e$B$"$j$^$9!#\e(B
 
 @code{nnvirtual} \e$B$O%a!<%k$H%K%e!<%9$NN>J}$N%0%k!<%W$r9=@.%0%k!<%W$H$9$k\e(B
 \e$B;v$,$G$-$^$9!#\e(B@code{nnvirtual} \e$B%0%k!<%W$N5-;v$KJVEz$9$k$H$-$O!"\e(B
 
 @code{nnvirtual} \e$B$O%a!<%k$H%K%e!<%9$NN>J}$N%0%k!<%W$r9=@.%0%k!<%W$H$9$k\e(B
 \e$B;v$,$G$-$^$9!#\e(B@code{nnvirtual} \e$B%0%k!<%W$N5-;v$KJVEz$9$k$H$-$O!"\e(B
@@ -16575,14 +16613,6 @@ file
 * Server Agent Commands::       
 @end menu
 
 * Server Agent Commands::       
 @end menu
 
-\e$B40A4$K%P%C%A$GF0:n$5$;$k$K$O!"%3%^%s%I9T$+$i0J2<$N$*$^$8$J$$$r<B9T$9$l$P\e(B
-\e$B$G$-$^$9!#\e(B
-
-@cindex gnus-agent-batch
-@example
-$ emacs -batch -l ~/.gnus.el -f gnus-agent-batch
-@end example
-
 @node Group Agent Commands
 @subsubsection \e$B%0%k!<%W%(!<%8%'%s%HL?Na\e(B
 
 @node Group Agent Commands
 @subsubsection \e$B%0%k!<%W%(!<%8%'%s%HL?Na\e(B
 
@@ -16906,9 +16936,12 @@ Gnus \e$B%(!<%8%'%s%H$K5-;v$r<hF@$5$;$k$N$O\e(B (\e$B$=$7$F$"$J$?$N=q$$$?2?$+$N%a%C
 \e$B%;!<%8$rEj9F$9$k$N$O\e(B)\e$B!"0lC6J*;v$r@5$7$/@_Dj$7$F$7$^$($PHs>o$K4JC1$G$9!#\e(B
 \e$B0J2<$N%7%'%k%9%/%j%W%H$OI,MW$J$3$H$rA4$F$d$C$F$/$l$k$G$7$g$&!#\e(B
 
 \e$B%;!<%8$rEj9F$9$k$N$O\e(B)\e$B!"0lC6J*;v$r@5$7$/@_Dj$7$F$7$^$($PHs>o$K4JC1$G$9!#\e(B
 \e$B0J2<$N%7%'%k%9%/%j%W%H$OI,MW$J$3$H$rA4$F$d$C$F$/$l$k$G$7$g$&!#\e(B
 
+\e$B0J2<$N<vJ8$r%3%^%s%I%i%$%s$G;H$&$3$H$K$h$C$F!"40A4$J%P%C%A%3%^%s%I$rAv$i\e(B
+\e$B$;$k$3$H$,$G$-$^$9\e(B:
+
 @example
 #!/bin/sh
 @example
 #!/bin/sh
-emacs -batch -l ~/.emacs -f gnus-agent-batch >/dev/null
+emacs -batch -l ~/.emacs -f -l ~/.gnus.el gnus-agent-batch >/dev/null 2>&1
 @end example
 
 @node Control Agents
 @end example
 
 @node Control Agents
@@ -17007,7 +17040,9 @@ Gnus Agent \e$B$O$h$/$"$kB>$N%*%U%i%$%s%K%e!<%9%j!<%@!<$N$h$&$K$OF0:n$7$^$;\e(B
 @table @dfn
 @item \e$B@\B3$5$l$F$$$k$H$-$K5-;v$rFI$s$@$i!"$=$l$O\e(B Agent \e$B$KF~$k$N$G$9$+\e(B?
 
 @table @dfn
 @item \e$B@\B3$5$l$F$$$k$H$-$K5-;v$rFI$s$@$i!"$=$l$O\e(B Agent \e$B$KF~$k$N$G$9$+\e(B?
 
-@strong{\e$B$$$$$(\e(B}\e$B!#\e(B
+@strong{\e$B$$$$$(\e(B}\e$B!#$3$NF0:n$rK>$`$N$J$i$P!"\e(B
+@code{gnus-select-article-hook} \e$B$K\e(B @code{gnus-agent-fetch-selected-article} \e$B$r\e(B
+\e$B2C$($F2<$5$$!#\e(B
 
 @item \e$B@\B3$5$l$F$$$k$H$-$K5-;v$rFI$s$G!"\e(BAgent \e$B$K5-;v$,B8:_$7$F$$$k>l9g!"\e(B
 \e$B$b$&0l2s%@%&%s%m!<%I$5$l$k$N$G$9$+\e(B?
 
 @item \e$B@\B3$5$l$F$$$k$H$-$K5-;v$rFI$s$G!"\e(BAgent \e$B$K5-;v$,B8:_$7$F$$$k>l9g!"\e(B
 \e$B$b$&0l2s%@%&%s%m!<%I$5$l$k$N$G$9$+\e(B?
@@ -19197,8 +19232,8 @@ gnus \e$B$ODL>o$[$H$s$I$N%P%C%U%!$G!"%]%$%s%H$r3F9T$N$"$i$+$8$a7h$a$i$l$?>l\e(B
 \e$B$-$^$9!#$=$N4X?t$O\e(B @code{gnus-goto-colon} \e$B$H8F$P$l$F$$$^$9!#\e(B
 
 \e$B$G$b!"$b$7$"$J$?$,9T$K%3%m%s$r4^$a$?$/$J$$$J$i$P!"$3$l$r07$&$?$a$N$*$=$i\e(B
 \e$B$-$^$9!#$=$N4X?t$O\e(B @code{gnus-goto-colon} \e$B$H8F$P$l$F$$$^$9!#\e(B
 
 \e$B$G$b!"$b$7$"$J$?$,9T$K%3%m%s$r4^$a$?$/$J$$$J$i$P!"$3$l$r07$&$?$a$N$*$=$i\e(B
-\e$B$/:G$b<j$4$m$JJ}K!$O\e(B @samp{%C} \e$B;X<(;R$r;H$&$3$H$G$9!#$"$J$?$N9T$N=qK!;E\e(B
-\e$BMM$NDj5A$K\e(B @samp{%C} \e$B$rF~$l$F$*$1$P!"\e(Bgnus \e$B$O$=$3$K%]%$%s%H$rCV$-$^$9!#\e(B
+\e$B$/:G$b<j$4$m$JJ}K!$O\e(B @samp{%*} \e$B;X<(;R$r;H$&$3$H$G$9!#$"$J$?$N9T$N=qK!;E\e(B
+\e$BMM$NDj5A$K\e(B @samp{%*} \e$B$rF~$l$F$*$1$P!"\e(Bgnus \e$B$O$=$3$K%]%$%s%H$rCV$-$^$9!#\e(B
 
 @node Tabulation
 @subsection \e$B@0Ns\e(B
 
 @node Tabulation
 @subsection \e$B@0Ns\e(B
@@ -19323,7 +19358,7 @@ gnus \e$B$ODL>o$[$H$s$I$N%P%C%U%!$G!"%]%$%s%H$r3F9T$N$"$i$+$8$a7h$a$i$l$?>l\e(B
 \e$B$*$)$C$H!#Fs$D$N%P%C%U%!$KIT;W5D$J\e(B 100% \e$B%?%0$,IU$$$F$$$^$9!#$=$7$F!"$"\e(B
 \e$B$N\e(B @code{horizontal} \e$B$C$F$$$&$b$N$O2?$G$7$g$&\e(B?
 
 \e$B$*$)$C$H!#Fs$D$N%P%C%U%!$KIT;W5D$J\e(B 100% \e$B%?%0$,IU$$$F$$$^$9!#$=$7$F!"$"\e(B
 \e$B$N\e(B @code{horizontal} \e$B$C$F$$$&$b$N$O2?$G$7$g$&\e(B?
 
-\e$B$b$7J,3d$N0l$D$N:G=i$NMWAG$,\e(B @code{horizontal} \e$B$G$"$C$?$J$i!"\e(Bgnus \e$B$O\e(B \e$B%&%#\e(B
+\e$B$b$7J,3d$N0l$D$N:G=i$NMWAG$,\e(B @code{horizontal} \e$B$G$"$C$?$J$i!"\e(Bgnus \e$B$O%&%#\e(B
 \e$B%s%I%&$r?eJ?$KJ,3d$7!"Fs$D$N%&%#%s%I%&$r2#$KJB$Y$^$9!#$3$l$i$N$=$l$>$l$N\e(B
 \e$B>.JR$NCf$G$O!"A4$F$rIaDL$NN.57$G9T$&;v$,$G$-$^$9!#\e(B@code{horizontal} \e$B$N8e\e(B
 \e$B$N?t;z$O!"$3$N>.JR$K2hLL$N$I$l$/$i$$$N3d9g$,M?$($i$l$k$+$r;XDj$7$^$9!#\e(B
 \e$B%s%I%&$r?eJ?$KJ,3d$7!"Fs$D$N%&%#%s%I%&$r2#$KJB$Y$^$9!#$3$l$i$N$=$l$>$l$N\e(B
 \e$B>.JR$NCf$G$O!"A4$F$rIaDL$NN.57$G9T$&;v$,$G$-$^$9!#\e(B@code{horizontal} \e$B$N8e\e(B
 \e$B$N?t;z$O!"$3$N>.JR$K2hLL$N$I$l$/$i$$$N3d9g$,M?$($i$l$k$+$r;XDj$7$^$9!#\e(B
@@ -19790,8 +19825,8 @@ Gnus \e$B$O$5$^$6$^$J@)8f;R\e(B @dfn{handlers} \e$B$rDj5A$9$k$3$H$K$h$C$F$=$N$h$&$J
 \e$B$O\e(B @code{gnus-demon-timestep} \e$BIC$N$3$H$G$9!#$3$l$O=i4|@_Dj$G$O\e(B 60 \e$B$G$9!#\e(B
 \e$B$b$7$3$NJQ?t$rJQ99$9$k$H!"A4$F$N@)8f;R$N7W;~$K1F6A$rM?$($^$9!#\e(B)
 
 \e$B$O\e(B @code{gnus-demon-timestep} \e$BIC$N$3$H$G$9!#$3$l$O=i4|@_Dj$G$O\e(B 60 \e$B$G$9!#\e(B
 \e$B$b$7$3$NJQ?t$rJQ99$9$k$H!"A4$F$N@)8f;R$N7W;~$K1F6A$rM?$($^$9!#\e(B)
 
-\e$B$H$$$&$o$1$G!"@)8f;R$rDI2C$7$?$1$l$P!"\e(B@file{.gnus} \e$B%U%!%$%k$K!"0J2<$N$h\e(B
-\e$B$&$J$b$N$r=q$/$3$H$,$G$-$^$9!#\e(B
+\e$B$H$$$&$o$1$G!"@)8f;R$rDI2C$7$?$1$l$P!"\e(B@file{.gnus.el} \e$B%U%!%$%k$K!"0J2<$N\e(B
+\e$B$h$&$J$b$N$r=q$/$3$H$,$G$-$^$9!#\e(B
 
 @findex gnus-demon-add-handler
 @lisp
 
 @findex gnus-demon-add-handler
 @lisp
@@ -19805,8 +19840,8 @@ Gnus \e$B$O$5$^$6$^$J@)8f;R\e(B @dfn{handlers} \e$B$rDj5A$9$k$3$H$K$h$C$F$=$N$h$&$J
 @findex gnus-demon-add-disconnection
 \e$B$3$N$?$a$N4{@=4X?t$,$$$/$D$+:n@.$5$l$F$$$^$9!#\e(B
 @code{gnus-demon-add-nocem}, @code{gnus-demon-add-disconnection}, @code{gnus-demon-add-nntp-close-connection}, @code{gnus-demon-add-scan-timestamps}, @code{gnus-demon-add-rescan}, @code{gnus-demon-add-scanmail} \e$B$G\e(B
 @findex gnus-demon-add-disconnection
 \e$B$3$N$?$a$N4{@=4X?t$,$$$/$D$+:n@.$5$l$F$$$^$9!#\e(B
 @code{gnus-demon-add-nocem}, @code{gnus-demon-add-disconnection}, @code{gnus-demon-add-nntp-close-connection}, @code{gnus-demon-add-scan-timestamps}, @code{gnus-demon-add-rescan}, @code{gnus-demon-add-scanmail} \e$B$G\e(B
-\e$B$9!#$3$l$i$NG=NO$,M_$7$1$l$P!"C1$K$3$l$i$N4X?t$r\e(B @file{.gnus} \e$B$KF~$l$F$/\e(B
-\e$B$@$5$$!#\e(B
+\e$B$9!#$3$l$i$NG=NO$,M_$7$1$l$P!"C1$K$3$l$i$N4X?t$r\e(B @file{.gnus.el} \e$B$KF~$l\e(B
+\e$B$F$/$@$5$$!#\e(B
 
 @findex gnus-demon-init
 @findex gnus-demon-cancel
 
 @findex gnus-demon-init
 @findex gnus-demon-cancel
@@ -20889,8 +20924,9 @@ Spam \e$B$H@o$&$?$a$N?7$7$$5;K!$O!"%a%C%;!<%8$rAw?.$9$k:]$K$$$/$P$/$+$NIiC4\e(B
 
 @code{spam.el} \e$B$N??$NL\E*$O\e(B spam \e$B8!=P$H_I2a$N$?$a$N41@)%;%s%?!<\e(B
 \e$B$r\e(B gnus \e$B$NCf$K;}$D$3$H$G$9!#$=$N$?$a$K\e(B @code{spam.el} \e$B$OFs$D$N$3$H$r9T$J\e(B
 
 @code{spam.el} \e$B$N??$NL\E*$O\e(B spam \e$B8!=P$H_I2a$N$?$a$N41@)%;%s%?!<\e(B
 \e$B$r\e(B gnus \e$B$NCf$K;}$D$3$H$G$9!#$=$N$?$a$K\e(B @code{spam.el} \e$B$OFs$D$N$3$H$r9T$J\e(B
-\e$B$$$^$9\e(B: \e$BF~$C$F$/$k%a!<%k$r_I2a$7!"\e(Bspam \e$B$H$7$FCN$i$l$k%a!<%k$rJ,@O$9$k$3\e(B
-\e$B$H$G$9!#\e(B
+\e$B$$$^$9\e(B: \e$BF~$C$F$/$k%a!<%k$r_I2a$7!"\e(Bspam \e$B$^$?$O\e(B ham \e$B$H$7$FCN$i$l$k%a!<%k$r\e(B
+\e$BJ,@O$9$k$3$H$G$9!#\e(B@emph{Ham} \e$B$O\e(B @code{spam.el} \e$B$N$$$?$k=j$G\e(B spam \e$B$G$O$J\e(B
+\e$B$$%a%C%;!<%8$r<($9$?$a$K;H$&L>A0$G$9!#\e(B
 
 \e$B$G$O\e(B @code{spam.el} \e$B$r\e(B load \e$B$9$k$H2?$,5/$-$k$G$7$g$&$+\e(B?  \e$BBh0l$K!"0J2<$N\e(B
 \e$B%-!<%\!<%IL?Na$,;H$($k$h$&$K$J$j$^$9\e(B:
 
 \e$B$G$O\e(B @code{spam.el} \e$B$r\e(B load \e$B$9$k$H2?$,5/$-$k$G$7$g$&$+\e(B?  \e$BBh0l$K!"0J2<$N\e(B
 \e$B%-!<%\!<%IL?Na$,;H$($k$h$&$K$J$j$^$9\e(B:
@@ -20907,7 +20943,8 @@ Spam \e$B$H@o$&$?$a$N?7$7$$5;K!$O!"%a%C%;!<%8$rAw?.$9$k:]$K$$$/$P$/$+$NIiC4\e(B
 
 \e$B8=:_$N5-;v$K\e(B spam \e$B$H$7$F0u$rIU$1!"$=$l$r\e(B @samp{H} \e$B0u$GI=<($7$^$9!#\e(B
 Spam \e$B5-;v$r8+$?$H$-$O$$$D$G$b!"%0%k!<%W$rH4$1$kA0$KI,$:\e(B @kbd{M-d} \e$B$G$=$N\e(B
 
 \e$B8=:_$N5-;v$K\e(B spam \e$B$H$7$F0u$rIU$1!"$=$l$r\e(B @samp{H} \e$B0u$GI=<($7$^$9!#\e(B
 Spam \e$B5-;v$r8+$?$H$-$O$$$D$G$b!"%0%k!<%W$rH4$1$kA0$KI,$:\e(B @kbd{M-d} \e$B$G$=$N\e(B
-\e$B35N,9T$K0u$rIU$1$k$h$&$K$7$F2<$5$$!#\e(B
+\e$B35N,9T$K0u$rIU$1$k$h$&$K$7$F2<$5$$!#$3$l$O\e(B @emph{spam} \e$B%0%k!<%W$NL$FI5-\e(B
+\e$B;v$KBP$7$F$O<+F0E*$K9T$J$o$l$^$9!#\e(B
 
 @item M s t
 @itemx S t
 
 @item M s t
 @itemx S t
@@ -20919,49 +20956,95 @@ Spam \e$B5-;v$r8+$?$H$-$O$$$D$G$b!"%0%k!<%W$rH4$1$kA0$KI,$:\e(B @kbd{M-d} \e$B$G$=$
 \e$B$3$N%3%^%s%I$,$A$c$s$HF/$/$?$a$K$O\e(B bogofilter \e$B$N=hM}$rM-8z$K$7$J$1$l$P$J\e(B
 \e$B$j$^$;$s!#\e(B
 
 \e$B$3$N%3%^%s%I$,$A$c$s$HF/$/$?$a$K$O\e(B bogofilter \e$B$N=hM}$rM-8z$K$7$J$1$l$P$J\e(B
 \e$B$j$^$;$s!#\e(B
 
-@xref{Bogofilter}.
+@xref{Bogofilter}\e$B!#\e(B
+
 @end table
 
 @end table
 
-gnus \e$B$O$"$J$?$,<u$1<h$C$?\e(B spam \e$B$+$i3X$V$3$H$,$G$-$^$9!#$"$J$?$,$7$J$1$l\e(B
-\e$B$P$J$i$J$$$N$O!"0l$D0J>e$N\e(B spam \e$B%0%k!<%W$K\e(B spam \e$B5-;v$r=8$a$F!"JQ\e(B
-\e$B?t\e(B @code{spam-junk-mailgroups} \e$B$rE,@Z$K@_Dj$9$k$3$H$G$9!#$3$l$i$N%0%k!<\e(B
-\e$B%W$G$O!"%G%#%U%)%k%H$G$9$Y$F$N%a%C%;!<%8$,\e(B spam \e$B$G$"$k$H2r<a$5$l$^$9\e(B: \e$B$=\e(B
-\e$B$l$i$K$O\e(B @samp{H} \e$B0u$,IU$-$^$9!#;~!9$3$l$i$N%a%C%;!<%8$rD4$Y$F$_$F!"$d$C\e(B
-\e$B$Q$j\e(B spam \e$B$G$O$J$+$C$?$9$Y$F$N5-;v$+$i\e(B @samp{H} \e$B0u$r>C$5$J$1$l$P$J$j$^$;\e(B
-\e$B$s!#\e(BSpam \e$B%0%k!<%W$+$iH4$1$k$H$-$K!"\e(B@samp{H} \e$B0u$,IU$$$?$^$^$N$9$Y$F$N%a%C\e(B
-\e$B%;!<%8$O\e(B spam \e$B8!=P%(%s%8%s\e(B (bogofilter\e$B!"\e(Bifile\e$B!"$=$NB>\e(B) \e$B$KEO$5$l$^$9!#\e(B
-@samp{H} \e$B0u$r>C$9$K$O\e(B @kbd{M-u} \e$B$G5-;v$r\e(B "\e$BL$FI\e(B" \e$B$K$9$k$+!"\e(B@kbd{d} \e$B$G$=$l\e(B
-\e$B$r\e(B spam \e$B$G$O$J$$$b$N$H$7$FFI$s$@$3$H$r@k8@$7$F2<$5$$!#%0%k!<%W$rH4$1$?$H\e(B
-\e$B$-!"$9$Y$F$N\e(B @samp{H} \e$B0u$,IU$$$?5-;v$O%;!<%V$5$l$?$+$I$&$+$K4X78L5$/!"\e(B
-Bogofilter \e$B$+\e(B ifile (@code{spam-use-bogofilter} \e$B$H\e(B @code{spam-use-ifile} \e$B$K\e(B
-\e$B$h$k\e(B) \e$B$KAw$i$l!"$=$l$i$r\e(B spam \e$B$NI8K\$H$7$F3X=,$7$^$9!#\e(B
+\e$B$^$?!"\e(B@code{spam.el} \e$B$r\e(B load \e$B$9$k$H!"$=$NJQ?t72$r%+%9%?%^%$%:$9$k$3$H$,\e(B
+\e$B$G$-$k$h$&$K$J$j$^$9!#\e(B@samp{spam} \e$BJQ?t%0%k!<%W$K$D$$\e(B
+\e$B$F\e(B @code{customize-group} \e$B$r;n$7$F$_$F2<$5$$!#\e(B
+
+Ham \e$B%W%m%;%C%5!<$H\e(B spam \e$B%W%m%;%C%5!<$N35G0$OHs>o$K=EMW$G$9!#$"$k%0%k!<%W\e(B
+\e$B$N\e(B ham \e$B%W%m%;%C%5!<$H\e(B spam \e$B%W%m%;%C%5!<$O!"\e(B@code{spam-process} \e$B%0%k!<%W\e(B
+\e$B%Q%i%a!<%?$+\e(B @code{gnus-spam-process-newsgroups} \e$BJQ?t$G@_Dj$9$k$3$H$,$G\e(B
+\e$B$-$^$9!#8e$GF1MM$N%a!<%k$r\e(B spam \e$B$G$O$J$$$H2r<a$G$-$k$h$&$K$9$k$?$a$K!"\e(B
+ham \e$B%W%m%;%C%5!<$OHs\e(B spam (@emph{ham}) \e$B$G$"$k$3$H$,$o$+$C$F$$$k%a!<%k$r\e(B
+\e$B<u$1<h$C$F!"2?$i$+$NJ}K!$G=hM}$7$^$9!#\e(BSpam \e$B%W%m%;%C%5!<$O!"8e$GF1MM\e(B
+\e$B$N\e(B spam \e$B$,8!=P$5$l$k$h$&$K!"\e(Bspam \e$B$G$"$k$3$H$,$o$+$C$F$$$k%a!<%k$r<u$1<h$C\e(B
+\e$B$F=hM}$7$^$9!#\e(B
+
+gnus \e$B$O$"$J$?$,<u$1<h$C$?\e(B spam \e$B$+$i3X$S$^$9!#$"$J$?$O0l$D0J>e$N\e(B spam \e$B%0\e(B
+\e$B%k!<%W$K\e(B spam \e$B5-;v$r=8$a$F!"JQ?t\e(B @code{spam-junk-mailgroups} \e$B$rE,@Z$K@_\e(B
+\e$BDj$b$7$/$O%+%9%?%^%$%:$7$J$1$l$P$J$j$^$;$s!#$^$?!"\e(Bspam \e$B$r4^$a$k%0%k!<%W\e(B
+\e$B$r!"$=$N%0%k!<%W%Q%i%a!<\e(B
+\e$B%?\e(B @code{spam-contents} \e$B$r\e(B @code{gnus-group-spam-classification-spam} \e$B$K\e(B
+\e$B@_Dj$9$k$+!"$^$?$O$=$l$KBP1~$9$kJQ\e(B
+\e$B?t\e(B @code{gnus-spam-newsgroup-contents} \e$B$r%+%9%?%^%$%:$9$k$3$H$K$h$C$F@k\e(B
+\e$B8@$9$k$3$H$,$G$-$^$9!#\e(B@code{spam-contents} \e$B%0%k!<%W%Q%i%a!<%?\e(B
+\e$B$H\e(B @code{gnus-spam-newsgroup-contents} \e$BJQ?t$O!"$=$l$i$N<oJL\e(B
+\e$B$r\e(B @code{gnus-group-spam-classification-ham} \e$B$K@_Dj$9$k$3$H$K$h$C$F!"\e(B
+@emph{ham} \e$B%0%k!<%W$G$"$k$3$H$r@k8@$9$k$?$a$K;H$&$3$H$b$G$-$^$9!#%0%k!<\e(B
+\e$B%W$,\e(B @code{spam-junk-mailgroups}, @code{spam-contents} \e$B$^$?\e(B
+\e$B$O\e(B @code{gnus-spam-newsgroup-contents} \e$B$G$"$k$3$H$r<($9J,N`$,9T$J$o$l$F\e(B
+\e$B$$$J$$$H!"$=$l$i$O\e(B @emph{\e$BL$J,N`\e(B} \e$B$G$"$k$H2r<a$5$l$^$9!#$9$Y$F$N%0%k!<%W\e(B
+\e$B$O%G%#%U%)%k%H$G$OL$J,N`$G$9!#\e(B
+
+Spam \e$B%0%k!<%W$G$O!"%G%#%U%)%k%H$G$9$Y$F$N%a%C%;!<%8$,\e(B spam \e$B$G$"$k$H2r<a\e(B
+\e$B$5$l$^$9\e(B: \e$B$=$N%0%k!<%W$KF~$k$H!"$=$l$i$K\e(B @samp{H} \e$B0u$,IU$-$^$9!#;~!9$3$l\e(B
+\e$B$i$N%a%C%;!<%8$rD4$Y$F$_$F!"$d$C$Q$j\e(B spam \e$B$G$O$J$+$C$?$9$Y$F$N5-;v$+$i\e(B
+@samp{H} \e$B0u$r>C$5$J$1$l$P$J$j$^$;$s!#\e(B@samp{H} \e$B0u$r>C$9$K$O\e(B @kbd{M-u} \e$B$G\e(B
+\e$B$=$N5-;v$r!VL$FI!W$K$9$k$+!"$"$k$$$O\e(B @kbd{d} \e$B$G\e(B spam \e$B$G$O$J$$$b$N$H$7$F\e(B
+\e$BFI$s$@$3$H$r@k8@$9$l$PNI$$$G$7$g$&!#%0%k!<%W$rH4$1$k$H$-!"$9$Y$F$N\e(B spam
+\e$B0u\e(B (@samp{H}) \e$B$,IU$$$?5-;v$O\e(B spam \e$B%W%m%;%C%5!<$KAw$i$l!"$=$l$i$r\e(B spam \e$B$N\e(B
+\e$BI8K\$H$7$F3X=,$7$^$9!#\e(B
 
 \e$B%a%C%;!<%8$OB>$N$$$m$$$m$JJ}K!$K$h$C$F$b>C5n$5$l$k$+$b$7$l$^$;$s$7!"\e(B
 
 \e$B%a%C%;!<%8$OB>$N$$$m$$$m$JJ}K!$K$h$C$F$b>C5n$5$l$k$+$b$7$l$^$;$s$7!"\e(B
-@code{spam-ham-marks-form} \e$B$,8e=R$N$h$&$K>e=q$-$5$l$J$1$l$P!"Dc$$%9%3%"\e(B
-\e$B$N$?$a$N\e(B @samp{Y} \e$B0u$HF1MM!"%G%#%U%)%k%H$N4{FI$+L@<(E*$J>C5n$N$?$a\e(B
+@code{spam-ham-marks} \e$B$,8e=R$N$h$&$K>e=q$-$5$l$J$1$l$P!"Dc$$%9%3%"$N$?$a\e(B
+\e$B$N\e(B @samp{Y} \e$B0u$HF1MM!"%G%#%U%)%k%H$N4{FI$+L@<(E*$J>C5n$N$?$a\e(B
 \e$B$N\e(B @samp{R} \e$B$H\e(B @samp{r} \e$B0u!"<+F0$^$?$OL@<(E*$J:o=|$N$?$a\e(B
 \e$B$N\e(B @samp{X} \e$B$H\e(B @samp{K} \e$B0u!"$=$l$i$9$Y$F$,\e(B spam \e$B$H$OL54X78$G$"$k$H2r<a$5\e(B
 \e$B$N\e(B @samp{R} \e$B$H\e(B @samp{r} \e$B0u!"<+F0$^$?$OL@<(E*$J:o=|$N$?$a\e(B
 \e$B$N\e(B @samp{X} \e$B$H\e(B @samp{K} \e$B0u!"$=$l$i$9$Y$F$,\e(B spam \e$B$H$OL54X78$G$"$k$H2r<a$5\e(B
-\e$B$l$^$9!#$3$N2>Dj$O!"FC$KK\J*$N\e(B spam \e$B$r8!=P$9$k$?$a$K>C5n\e(B (kill) \e$B%U%!%$%k\e(B
-\e$B$+%9%3%"%U%!%$%k$r;H$C$F$$$k>l9g$O4V0c$C$F$$$k$+$b$7$l$^$;$s!#$=$&$G$"$l\e(B
-\e$B$P\e(B @code{spam-ham-marks-form} \e$B$rD4@0$9$k$Y$-$G$9!#%0%k!<%W$rH4$1$k$H$-$K!"\e(B
-\e$B>e5-$N0u$,IU$$$?$9$Y$F$N%;!<%V$5$l$F$$$J$$5-;v$O\e(B Bogofilter \e$B$+\e(B ifile \e$B$K\e(B
-\e$BAw$i$l!"$=$l$i$r\e(B spam \e$B$G$O$J$$I8K\$H$7$F3X=,$7$^$9!#0U?^E*$K$?$/$5$s$N>C\e(B
-\e$B5n$r9T$J$&$H!"$?$^$K$=$l$O8+$F$$$J$$\e(B @samp{K} \e$B0u$,IU$$$?5-;v$G=*$o$k$+$b\e(B
-\e$B$7$l$^$;$s!#$=$7$F$=$l$i$O6vA3$K\e(B spam \e$B$r4^$s$G$$$k$+$b$7$l$^$;$s!#:G$bNI\e(B
-\e$B$$$N$O!"K\Ev$N\e(B spam \e$B$K\e(B @samp{H} \e$B$,IU$$$F$$$F!"B>$K2?$bL5$$$3$H$r3N$+$a$k\e(B
-\e$B$3$H$G$9!#\e(B
-
-\e$BB>$N$9$Y$F$N%^!<%/$,\e(B Bogofilter \e$B$"$k$$$O\e(B ifile \e$B$NF0:n$NA0Ds$H$J$k>r7oIU\e(B
-\e$B$1$K4sM?$9$k$o$1$G$O$"$j$^$;$s!#$H$j$o$12D;k\e(B (ticked)\e$B!"J]N1\e(B (dormant) \e$B$^\e(B
-\e$B$?$O\e(B soup \e$B$5$l$F$$$k5-;v$O!"K\Ev$K>C5n$5$l$?8e$G4sM?$9$k$N$,E,Ev$J$N$G!"\e(B
-\e$B$=$l$i$rAa$^$C$F;H$&I,MW$O$"$j$^$;$s!#L@<(E*$K4|8B@Z$l>C5n$5$l$?5-;v$O4s\e(B
-\e$BM?$7$^$;$s!#%3%^%s%I\e(B @kbd{E} \e$B$O\e(B Bogofilter \e$B$^$?$O\e(B ifile \e$B$,>o$K8+$k$3$HL5\e(B
-\e$B$7$K5-;v$r<h$j=|$/J}K!$G$9!#\e(B
-
-@strong{TODO: @code{spam-use-ifile} \e$B$O%0%k!<%W$rH4$1$k$H$-$K5-;v$r=hM}$7\e(B
-\e$B$^$;$s!#;d\e(B (\e$BLuCm\e(B: Teodor Zlatanov) \e$B$O$=$N5!G=$,\e(B @code{spam.el} \e$B$G$O$J$/\e(B
-\e$B$F\e(B @code{ifile-gnus.el} \e$B$G9T$J$o$l$k$Y$-$@$H;W$&$N$G!"\e(B
-@code{ifile-gnus.el} \e$B$N:n<T$+$i$N\e(B info \e$B$rBT$C$F$$$^$9!#\e(B}
+\e$B$l$^$9!#$3$N2>Dj$O!"K\J*$N\e(B spam \e$B$r8!=P$9$k$?$a$K>C5n\e(B (kill) \e$B%U%!%$%k$+%9\e(B
+\e$B%3%"%U%!%$%k$rFCJL$K;H$C$F$$$k>l9g$O4V0c$C$F$$$k$+$b$7$l$^$;$s!#$=$&$G$"\e(B
+\e$B$l$P\e(B @code{spam-ham-marks} \e$BJQ?t$rD4@0$9$k$Y$-$G$9!#\e(B
+
+@defvar spam-ham-marks
+\e$B$3$NJQ?t$r\e(B ham \e$B$G$"$k$H2r<a$7$?$$0u$N%j%9%H$K@_Dj$9$k$3$H$,$G$-$^$9!#%G%#\e(B
+\e$B%U%)%k%H$G$O!">C5n\e(B (deleted)\e$B!"4{FI\e(B (read)\e$B!":o=|\e(B (killed)\e$B!"\e(Bkill \e$B%U%!%$%k\e(B
+\e$B$K$"$k$b$N\e(B (kill-filed) \e$B$*$h$SDc$$%9%3%"\e(B (low-score) \e$B0u$N%j%9%H$G$9!#\e(B
+@end defvar
+
+@defvar spam-spam-marks
+\e$B$3$NJQ?t$r\e(B spam \e$B$G$"$k$H2r<a$7$?$$0u$N%j%9%H$K@_Dj$9$k$3$H$,$G$-$^$9!#%G%#\e(B
+\e$B%U%)%k%H$G$O\e(B spam \e$B0u$@$1$r;}$D%j%9%H$G$9!#\e(B
+@end defvar
+
+\e$B%0%k!<%W$rH4$1$k$H$-$K\e(B (\e$B$=$N%0%k!<%W$,\e(B @emph{\e$B2?\e(B} \e$B$G$"$C$F$b\e(B)\e$B!"$=\e(B
+\e$B$N\e(B @code{spam-contents} \e$B$NJ,N`$K$+$+$o$i$:!"\e(Bspam \e$B0u$,IU$$$F$$$k$9$Y$F$N\e(B
+\e$B5-;v$O\e(B spam \e$B%W%m%;%C%5!<$KAw$i$l!"$=$l$i$r\e(B spam \e$B$NI8K\$H$7$F3X=,$7$^$9!#\e(B
+\e$B0U?^E*$K$?$/$5$s$N>C5n$r9T$J$&$H!"$?$^$K$=$l$O8+$F$$$J$$\e(B @samp{K} \e$B0u$,IU\e(B
+\e$B$$$?5-;v$G=*$o$k$+$b$7$l$^$;$s!#$=$7$F$=$l$i$O6vA3$K\e(B spam \e$B$r4^$s$G$$$k$+\e(B
+\e$B$b$7$l$^$;$s!#:G$bNI$$$N$O!"K\Ev$N\e(B spam \e$B$K\e(B @samp{H} \e$B$,IU$$$F$$$F!"B>$K2?\e(B
+\e$B$bL5$$$3$H$r3N$+$a$k$3$H$G$9!#\e(B
+
+@emph{Spam} \e$B%0%k!<%W$rH4$1$k$H$-$K!"\e(Bspam \e$B0u$,IU$$$F$$$k$9$Y$F$N5-;v\e(B
+\e$B$K$O\e(B spam \e$B%W%m%;%C%5!<$G=hM}$7$?8e$G4|8B@Z$l>C5n$N0u$,IU$1$i$l$^$9!#$3$l\e(B
+\e$B$O\e(B @emph{\e$BL$J,N`\e(B} \e$B$^$?$O\e(B @emph{ham} \e$B%0%k!<%W$KBP$7$F$O9T$J$o$l$^$;$s!#$5\e(B
+\e$B$i$K\e(B spam \e$B%0%k!<%W$K$"$k$I$N\e(B @strong{ham} \e$B5-;v$b!"\e(B
+@code{ham-process-destination} \e$B%0%k!<%W%Q%i%a!<%?\e(B
+\e$B$+\e(B @code{gnus-ham-process-destinations} \e$BJQ?t$N$I$A$i$+$G7h$a$i$l$F$$$k>l\e(B
+\e$B=j$K0\$5$l$^$9!#>l=j$H$$$&$N$O%0%k!<%WL>$N$3$H$G$9!#\e(B
+@code{ham-process-destination} \e$B%Q%i%a!<%?$,@_Dj$5$l$F$$$J$$$H!"\e(Bspam \e$B5-;v\e(B
+\e$B$OC1$K4|8B@Z$l>C5n$5$l$^$9!#\e(B
+
+@emph{Ham} \e$B%0%k!<%W$rH4$1$k$H$-$K!"\e(Bham \e$B0u$,IU$$$F$$$k$9$Y$F$N5-;v\e(B
+\e$B$O\e(B ham \e$B%W%m%;%C%5!<$KAw$i$l!"$=$l$i$r\e(B spam \e$B$G$O$J$$I8K\$H$7$F3X=,$7$^$9!#\e(B
+
+@emph{Ham} \e$B$^$?$O\e(B @emph{\e$BL$J,N`\e(B} \e$B%0%k!<%W$rH4$1$k$H$-$K!"$9$Y$F\e(B
+\e$B$N\e(B @strong{spam} \e$B5-;v$O!"\e(B@code{spam-process-destination} \e$B%0%k!<%W%Q%i%a!<\e(B
+\e$B%?$+\e(B @code{gnus-spam-process-destinations} \e$BJQ?t$N$I$A$i$+$G7h$a$i$l$F$$\e(B
+\e$B$k>l=j$K0\$5$l$^$9!#>l=j$H$$$&$N$O%0%k!<%WL>$N$3$H$G$9!#\e(B
+@code{spam-process-destination} \e$B%Q%i%a!<%?$,@_Dj$5$l$F$$$J$$$H!"\e(Bspam \e$B5-\e(B
+\e$B;v$OC1$K4|8B@Z$l>C5n$5$l$^$9!#\e(B
 
 \e$BF~$C$F$/$k%a!<%k$r_I2a$9$kL\E*$G\e(B @code{spam.el} \e$B$r;H$&$K$O!"FC5iJ,3d%j%9\e(B
 \e$B%H\e(B @code{nnmail-split-fancy} \e$B$^$?$O\e(B @code{nnimap-split-fancy} \e$B$K0J2<$rDI\e(B
 
 \e$BF~$C$F$/$k%a!<%k$r_I2a$9$kL\E*$G\e(B @code{spam.el} \e$B$r;H$&$K$O!"FC5iJ,3d%j%9\e(B
 \e$B%H\e(B @code{nnmail-split-fancy} \e$B$^$?$O\e(B @code{nnimap-split-fancy} \e$B$K0J2<$rDI\e(B
@@ -20976,18 +21059,28 @@ Bogofilter \e$B$+\e(B ifile (@code{spam-use-bogofilter} \e$B$H\e(B @code{spam-use-if
 \e$B$O\e(B @code{nnimap-split-fancy} \e$B$+$i8F$P$l$k$3$H$KCm0U$7$F2<$5$$!#\e(B
 
 @code{spam-split} \e$B4X?t$OF~$C$F$/$k%a!<%k$r=hM}$7!"\e(Bspam \e$B$H;W$o$l$k%a!<%k\e(B
 \e$B$O\e(B @code{nnimap-split-fancy} \e$B$+$i8F$P$l$k$3$H$KCm0U$7$F2<$5$$!#\e(B
 
 @code{spam-split} \e$B4X?t$OF~$C$F$/$k%a!<%k$r=hM}$7!"\e(Bspam \e$B$H;W$o$l$k%a!<%k\e(B
-\e$B$rJQ?t\e(B @code{spam-split-group} \e$B$GM?$($i$l$kL>A0$N%0%k!<%W$KAw$j$^$9!#DL\e(B
-\e$B>o$=$N%0%k!<%WL>$O\e(B @samp{spam} \e$B$G$9!#\e(B
+\e$B$rJQ?t\e(B @code{spam-split-group} \e$B$GM?$($i$l$kL>A0$N%0%k!<%W$KAw$j$^$9!#%G%#\e(B
+\e$B%U%)%k%H$G$O$=$N%0%k!<%WL>$O\e(B @samp{spam} \e$B$G$9$,!"%+%9%?%^%$%:$9$k$3$H$O\e(B
+\e$B2DG=$G$9!#\e(B
+
+@emph{TODO: \e$B8=>u\e(B spam.el \e$B$O5-;v$r%P%C%/%(%s%I$KEjF~$9$k$3$H$@$1$r%5%]!<\e(B
+\e$B%H$7$^$9!#5-;v$,$b$O$d\e(B spam \e$B$^$?$O\e(B ham \e$B$G$O$J$$$H\e(B spam.el \e$B$KEA$($kJ}K!$O\e(B
+\e$B$"$j$^$;$s!#\e(B}
+
+@emph{TODO: spam.el \e$B$O$9$Y$F$NE}7W%G!<%?%Y!<%9$r71N}$9$k$?$a$N0lDjITJQ$N\e(B
+\e$BJ}K!$rDs6!$9$kI,MW$,$"$j$^$9!#$$$/$D$+$O$=$N5!G=$r<+A0$G;}$C$F$$$^$9$,!"\e(B
+\e$B$=$&$G$J$$$b$N$b$"$j$^$9!#\e(B}
 
 \e$B0J2<$O\e(B @code{spam-split} \e$B$NF0:n$r@)8f$9$k$?$a$K;H$&$3$H$,$G$-$k3F<o$NJ}\e(B
 
 \e$B0J2<$O\e(B @code{spam-split} \e$B$NF0:n$r@)8f$9$k$?$a$K;H$&$3$H$,$G$-$k3F<o$NJ}\e(B
-\e$BK!$G$9!#\e(B
+\e$BK!$H!"$=$l$i$KBP1~$9$k\e(B spam \e$B$H\e(B ham \e$B$N%W%m%;%C%5!<$G$9\e(B:
 
 @menu
 * Blacklists and Whitelists::   
 * BBDB Whitelists::             
 * Blackholes::                  
 * Bogofilter::                  
 
 @menu
 * Blacklists and Whitelists::   
 * BBDB Whitelists::             
 * Blackholes::                  
 * Bogofilter::                  
-* Ifile spam filtering::        
+* ifile spam filtering::        
+* spam-stat spam filtering::    
 * Extending spam.el::           
 @end menu
 
 * Extending spam.el::           
 @end menu
 
@@ -20999,31 +21092,56 @@ Bogofilter \e$B$+\e(B ifile (@code{spam-use-bogofilter} \e$B$H\e(B @code{spam-use-if
 @cindex spam.el
 
 @defvar spam-use-blacklist
 @cindex spam.el
 
 @defvar spam-use-blacklist
-\e$B%V%i%C%/%j%9%H$r;H$$$?$$$J$i$P!"$3$NJQ?t$r\e(B t (\e$B%G%#%U%)%k%H\e(B) \e$B$K@_Dj$7$F2<\e(B
-\e$B$5$$!#\e(B
+\e$BF~$C$F$/$k%a!<%k$rJ,3d$9$k$H$-$K%V%i%C%/%j%9%H$r;H$$$?$$>l9g$O!"$3$NJQ?t\e(B
+\e$B$r\e(B t \e$B$K@_Dj$7$F2<$5$$!#Aw?.<T$,%V%i%C%/%j%9%H$K:\$C$F$$$k%a%C%;!<%8\e(B
+\e$B$O\e(B @code{spam-split-group} \e$B$KAw$i$l$^$9!#$3$l$OL@<(E*$J_I2a4o$G!"Aw?.<T\e(B
+\e$B$,\e(B spammer \e$B$G$"$k$3$H$,Dj5A$5$l$F$$$k%a!<%k$KBP$7$F$@$1F0:n$7$^$9!#\e(B
 @end defvar
 
 @defvar spam-use-whitelist
 @end defvar
 
 @defvar spam-use-whitelist
-\e$B%[%o%$%H%j%9%H;H$$$?$$>l9g$O!"$3$NJQ?t$r\e(B t \e$B$K@_Dj$7$F2<$5$$!#\e(B
+\e$BF~$C$F$/$k%a!<%k$rJ,3d$9$k$H$-$K%[%o%$%H%j%9%H$r;H$$$?$$>l9g$O!"$3$NJQ?t\e(B
+\e$B$r\e(B t \e$B$K@_Dj$7$F2<$5$$!#Aw?.<T$,%[%o%$%H%j%9%H$K:\$C$F$$$J$$%a%C%;!<%8\e(B
+\e$B$O\e(B @code{spam-split-group} \e$B$KAw$i$l$^$9!#$3$l$O0EL[$N_I2a4o$G!"B>$NJ}K!\e(B
+\e$B$GEA$($i$l$J$+$C$?$J$i$P!"$9$Y$F$N?M$r\e(B spammer \e$B$G$"$k$H8+$J$7$^$9!#Cm0U\e(B
+\e$B$7$F;H$C$F2<$5$$!#\e(B
+@end defvar
+
+@defvar gnus-group-spam-exit-processor-blacklist
+\e$B$3$N%7%s%\%k$r!"%0%k!<%W%Q%i%a!<%?$N%+%9%?%^%$%:$K$h$C$F%0%k!<%W\e(B
+\e$B$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($k$+!"$^$?\e(B
+\e$B$O\e(B @code{gnus-spam-process-newsgroups} \e$BJQ?t$K2C$($F2<$5$$!#$3$N%7%s%\%k\e(B
+\e$B$,%0%k!<%W$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($i$l$k$H!"\e(Bspam \e$B0u$,IU$$\e(B
+\e$B$?5-;v$NAw?.<T$,%V%i%C%/%j%9%H$KDI2C$5$l$^$9!#\e(B
+@end defvar
+
+@defvar gnus-group-ham-exit-processor-whitelist
+\e$B$3$N%7%s%\%k$r!"%0%k!<%W%Q%i%a!<%?$N%+%9%?%^%$%:$K$h$C$F%0%k!<%W\e(B
+\e$B$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($k$+!"$^$?\e(B
+\e$B$O\e(B @code{gnus-spam-process-newsgroups} \e$BJQ?t$K2C$($F2<$5$$!#$3$N%7%s%\%k\e(B
+\e$B$,%0%k!<%W$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($i$l$k$H!"\e(Bham \e$B0u$,IU$$\e(B
+\e$B$?\e(B @emph{ham} \e$B%0%k!<%W$N5-;v$NAw?.<T$,%[%o%$%H%j%9%H$KDI2C$5$l$^$9!#$3\e(B
+\e$B$N\e(B ham \e$B%W%m%;%C%5!<$O\e(B @emph{spam} \e$B$+\e(B @emph{\e$BL$J,N`\e(B} \e$B%0%k!<%W$K$O8z2L$r5Z\e(B
+\e$B$\$5$J$$$3$H$KCm0U$7$F2<$5$$!#\e(B
 @end defvar
 
 \e$B%V%i%C%/%j%9%H$O!"$"$J$?$,\e(B spam \e$B$NAw?.<T$@$H9M$($k%"%I%l%9$K9gCW$9$k@55,\e(B
 \e$BI=8=$N%j%9%H$G$9!#Nc$($P\e(B @samp{vmadmin.com} \e$B$NC/$+$i$G$bMh$k%a!<%k$rAK;_\e(B
 \e$B$9$k$K$O!"$"$J$?$N%V%i%C%/%j%9%H$K\e(B @samp{vmadmin.com} \e$B$rF~$l$F2<$5$$!#6u\e(B
 @end defvar
 
 \e$B%V%i%C%/%j%9%H$O!"$"$J$?$,\e(B spam \e$B$NAw?.<T$@$H9M$($k%"%I%l%9$K9gCW$9$k@55,\e(B
 \e$BI=8=$N%j%9%H$G$9!#Nc$($P\e(B @samp{vmadmin.com} \e$B$NC/$+$i$G$bMh$k%a!<%k$rAK;_\e(B
 \e$B$9$k$K$O!"$"$J$?$N%V%i%C%/%j%9%H$K\e(B @samp{vmadmin.com} \e$B$rF~$l$F2<$5$$!#6u\e(B
-\e$B$N%V%i%C%/%j%9%H$G;O$a$k$H!"\e(B@code{spam-use-blacklist} \e$BJQ?t$r%;%C%H$9$k$3\e(B
-\e$B$H$K$h$C$F32$r@8$8$J$$$N$G!"$=$l$O%G%#%U%)%k%H$G%;%C%H$5$l$F$$$^$9!#%V%i%C\e(B
-\e$B%/%j%9%H$N3F9`L\$O\e(B Emacs \e$B$N@55,I=8=%7%s%?%C%/%9$r;H$$$^$9!#\e(B
+\e$B$N%V%i%C%/%j%9%H$G;O$a$^$7$g$&!#%V%i%C%/%j%9%H$N3F9`L\$O\e(B Emacs \e$B$N@55,I=\e(B
+\e$B8=%7%s%?%C%/%9$r;H$$$^$9!#\e(B
 
 \e$B5U$K!"%[%o%$%H%j%9%H$O2?$N%"%I%l%9$,@5Ev$@$H9M$($i$l$k$+$r9p$2$^$9!#%[%o\e(B
 \e$B%$%H%j%9%H$KL5$$$9$Y$F$N%"%I%l%9$O\e(B spammers \e$B$@$H8+$J$5$l$^$9!#%[%o%$%H%j\e(B
 
 \e$B5U$K!"%[%o%$%H%j%9%H$O2?$N%"%I%l%9$,@5Ev$@$H9M$($i$l$k$+$r9p$2$^$9!#%[%o\e(B
 \e$B%$%H%j%9%H$KL5$$$9$Y$F$N%"%I%l%9$O\e(B spammers \e$B$@$H8+$J$5$l$^$9!#%[%o%$%H%j\e(B
-\e$B%9%H$,Hs>o$K9-$$HO0O$rM-8z$HG'$a$k$h$&$K$J$C$F$$$J$$$H!"$?$V$s$3$N%*%W%7%g\e(B
+\e$B%9%H$,Hs>o$K9-$$HO0O$rM-8z$HG'$a$k$+$^$?$O42MF$G$J$$$H!"$?$V$s$3$N%*%W%7%g\e(B
 \e$B%s$O$[$H$s$I$N\e(B gnus \e$B$N%f!<%6!<$K$H$C$FM-1W$G$O$"$j$^$;$s!#\e(B
 @ref{BBDB Whitelists} \e$B$b8+$F2<$5$$!#%[%o%$%H%j%9%H$N3F9`L\$O\e(B Emacs \e$B$N@5\e(B
 \e$B5,I=8=%7%s%?%C%/%9$r;H$$$^$9!#\e(B
 
 \e$B%s$O$[$H$s$I$N\e(B gnus \e$B$N%f!<%6!<$K$H$C$FM-1W$G$O$"$j$^$;$s!#\e(B
 @ref{BBDB Whitelists} \e$B$b8+$F2<$5$$!#%[%o%$%H%j%9%H$N3F9`L\$O\e(B Emacs \e$B$N@5\e(B
 \e$B5,I=8=%7%s%?%C%/%9$r;H$$$^$9!#\e(B
 
-\e$B%V%i%C%/%j%9%H$H%[%o%$%H%j%9%H$N=j:_$O\e(B @code{spam-directory} \e$BJQ?t\e(B (\e$B%G%#\e(B
-\e$B%U%)%k%H$O\e(B @file{~/News/spam}) \e$B$G%+%9%?%^%$%:$G$-$^$9!#%V%i%C%/%j%9%H$H\e(B
-\e$B%[%o%$%H%j%9%H$N%U%!%$%k$O$=$N%G%#%l%/%H%j$K$"$j!"$=$l$>\e(B
+\e$B%V%i%C%/%j%9%H$H%[%o%$%H%j%9%H$N%U%!%$%k$N=j:_$O!"\e(B
+@code{spam-directory} \e$BJQ?t\e(B (\e$B%G%#%U%)%k%H$O\e(B @file{~/News/spam}) \e$B$^$?\e(B
+\e$B$OD>@\\e(B @code{spam-whitelist} \e$B$H\e(B @code{spam-blacklist} \e$BJQ?t$G%+%9%?%^%$%:\e(B
+\e$B$9$k$3$H$,$G$-$^$9!#%[%o%$%H%j%9%H$H%V%i%C%/%j%9%H$N%U%!%$%k$O!"%G%#%U%)\e(B
+\e$B%k%H$G$O\e(B @code{spam-directory} \e$B$N%G%#%l%/%H%j$K$"$j!"$=$l$>\e(B
 \e$B$l\e(B @file{whitelist} \e$B$H\e(B @file{blacklist} \e$B$H$$$&L>A0$,IU$1$i$l$^$9!#\e(B
 
 @node BBDB Whitelists
 \e$B$l\e(B @file{whitelist} \e$B$H\e(B @file{blacklist} \e$B$H$$$&L>A0$,IU$1$i$l$^$9!#\e(B
 
 @node BBDB Whitelists
@@ -21033,16 +21151,26 @@ Bogofilter \e$B$+\e(B ifile (@code{spam-use-bogofilter} \e$B$H\e(B @code{spam-use-if
 @cindex BBDB, spam filtering
 @cindex spam.el
 
 @cindex BBDB, spam filtering
 @cindex spam.el
 
-@defvar spam-use-bbdb
+@defvar spam-use-BBDB
 
 @code{spam-use-whitelist} (@pxref{Blacklists and Whitelists}) \e$B$K;w$F$$$^\e(B
 \e$B$9$,!"%[%o%$%H%j%9%H$N%"%I%l%9$N8;$H$7$F!"@55,I=8=$G$O$J$$\e(B BBDB \e$B$r;H$$$^\e(B
 
 @code{spam-use-whitelist} (@pxref{Blacklists and Whitelists}) \e$B$K;w$F$$$^\e(B
 \e$B$9$,!"%[%o%$%H%j%9%H$N%"%I%l%9$N8;$H$7$F!"@55,I=8=$G$O$J$$\e(B BBDB \e$B$r;H$$$^\e(B
-\e$B$9!#\e(B@code{spam-use-bbdb} \e$B$r$A$c$s$HF0:n$5$;$k$K$O\e(B BBDB \e$B$r\e(B load \e$B$7$J$1$l\e(B
+\e$B$9!#\e(B@code{spam-use-BBDB} \e$B$r$A$c$s$HF0:n$5$;$k$K$O\e(B BBDB \e$B$r\e(B load \e$B$7$J$1$l\e(B
 \e$B$P$J$j$^$;$s!#\e(BBBDB \e$B$K$"$k%"%I%l%9$@$1$,5v$5$l!"B>$O$9$Y$F\e(B spam \e$B$H$7$FJ,\e(B
 \e$BN`$5$l$^$9!#\e(B
 
 @end defvar
 
 \e$B$P$J$j$^$;$s!#\e(BBBDB \e$B$K$"$k%"%I%l%9$@$1$,5v$5$l!"B>$O$9$Y$F\e(B spam \e$B$H$7$FJ,\e(B
 \e$BN`$5$l$^$9!#\e(B
 
 @end defvar
 
+@defvar gnus-group-ham-exit-processor-BBDB
+\e$B$3$N%7%s%\%k$r!"%0%k!<%W%Q%i%a!<%?$N%+%9%?%^%$%:$K$h$C$F%0%k!<%W\e(B
+\e$B$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($k$+!"$^$?\e(B
+\e$B$O\e(B @code{gnus-spam-process-newsgroups} \e$BJQ?t$K2C$($F2<$5$$!#$3$N%7%s%\%k\e(B
+\e$B$,%0%k!<%W$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($i$l$k$H!"\e(Bham \e$B0u$,IU$$\e(B
+\e$B$?\e(B @emph{ham} \e$B%0%k!<%W$N5-;v$NAw?.<T$,\e(B BBDB \e$B$KDI2C$5$l$^$9!#$3$N\e(B ham \e$B%W\e(B
+\e$B%m%;%C%5!<$O\e(B @emph{spam} \e$B$+\e(B @emph{\e$BL$J,N`\e(B} \e$B%0%k!<%W$K$O8z2L$r5Z$\$5$J$$$3\e(B
+\e$B$H$KCm0U$7$F2<$5$$!#\e(B
+@end defvar
+
 @node Blackholes
 @subsubsection \e$B%V%i%C%/%[!<%k\e(B
 @cindex spam filtering
 @node Blackholes
 @subsubsection \e$B%V%i%C%/%[!<%k\e(B
 @cindex spam filtering
@@ -21067,6 +21195,22 @@ Bogofilter \e$B$+\e(B ifile (@code{spam-use-bogofilter} \e$B$H\e(B @code{spam-use-if
 
 @end defvar
 
 
 @end defvar
 
+@defvar spam-blackhole-servers
+
+\e$B%V%i%C%/%[!<%k!&%A%'%C%/$N$?$a$K0U8+$r5a$a$k%5!<%P!<$N%j%9%H$G$9!#\e(B
+
+@end defvar
+
+@defvar spam-use-dig
+
+@code{dns.el} \e$B%Q%C%1!<%8$NBe$o$j$K\e(B @code{dig.el} \e$B%Q%C%1!<%8$r;H$$$^$9!#\e(B
+\e$B%G%#%U%)%k%H$N@_Dj$G$"$k\e(B t \e$B$,?d>)$5$l$^$9!#\e(B
+
+@end defvar
+
+\e$B%V%i%C%/%[!<%k!&%A%'%C%/$OF~$C$FMh$k%a!<%k$KBP$7$F$@$19T$J$o$l$^$9!#%V%i%C\e(B
+\e$B%/%[!<%k$K\e(B spam \e$B$^$?$O\e(B ham \e$B%W%m%;%C%5!<$O$"$j$^$;$s!#\e(B
+
 @node Bogofilter
 @subsubsection Bogofilter
 @cindex spam filtering
 @node Bogofilter
 @subsubsection Bogofilter
 @cindex spam filtering
@@ -21075,10 +21219,10 @@ Bogofilter \e$B$+\e(B ifile (@code{spam-use-bogofilter} \e$B$H\e(B @code{spam-use-if
 
 @defvar spam-use-bogofilter
 
 
 @defvar spam-use-bogofilter
 
-Eric Raymond \e$B$N?WB.$J\e(B Bogofilter \e$B$r;HMQ$7$?$$>l9g$O!"$3$NJQ?t$r%;%C%H$7\e(B
-\e$B$F$/$@$5$$!#$3$l$O!"%P!<%8%g%s\e(B 0.4 \e$B$N%m!<%+%k$K%Q%C%A$,Ev$?$C$?%3%T!<$G\e(B
-\e$B%F%9%H$5$l$^$7$?!#\e(B@code{spam.el} \e$B$K$"$k%$%s%9%H!<%k$K4X$9$k%3%a%s%H$rFI\e(B
-\e$B$s$G3N$+$a$F2<$5$$!#\e(B
+Eric Raymond \e$B$N?WB.$J\e(B Bogofilter \e$B$r\e(B @code{spam-split} \e$B$K;HMQ$7$?$$>l9g$O!"\e(B
+\e$B$3$NJQ?t$r%;%C%H$7$F$/$@$5$$!#$3$l$O!"%P!<%8%g%s\e(B 0.4 \e$B$N%m!<%+%k$K%Q%C%A\e(B
+\e$B$,Ev$?$C$?%3%T!<$G%F%9%H$5$l$^$7$?!#\e(B@code{spam.el} \e$B$K$"$k%$%s%9%H!<%k$K\e(B
+\e$B4X$9$k%3%a%s%H$rFI$s$G3N$+$a$F2<$5$$!#\e(B
 
 Spam \e$B5-;v$@$1$N\e(B @samp{H} \e$B0u$r4XO"IU$1$k:G>.$N@$OC$K$h$C$F!"\e(BBogofilter \e$B%H\e(B
 \e$B%l!<%K%s%0$O$9$Y$F$+$J$j<+F0E*$K$J$j$^$9!#3F%+%F%4%j!<$N\e(B spam \e$B$+$=$&$G$J\e(B
 
 Spam \e$B5-;v$@$1$N\e(B @samp{H} \e$B0u$r4XO"IU$1$k:G>.$N@$OC$K$h$C$F!"\e(BBogofilter \e$B%H\e(B
 \e$B%l!<%K%s%0$O$9$Y$F$+$J$j<+F0E*$K$J$j$^$9!#3F%+%F%4%j!<$N\e(B spam \e$B$+$=$&$G$J\e(B
@@ -21089,34 +21233,113 @@ Spam \e$B5-;v$@$1$N\e(B @samp{H} \e$B0u$r4XO"IU$1$k:G>.$N@$OC$K$h$C$F!"\e(BBogofilte
 spam \e$BEY\e(B?) \e$B%9%3%"\e(B (0.0\e$B!A\e(B1.0) \e$B$r!"%9%3%"$K:G$bCx$7$/4sM?$9$k5-;v$N8l$H$$$C\e(B
 \e$B$7$g$K!"B>$N%P%C%U%!$KI=<($9$k$3$H$rB%$7$^$9!#\e(B
 
 spam \e$BEY\e(B?) \e$B%9%3%"\e(B (0.0\e$B!A\e(B1.0) \e$B$r!"%9%3%"$K:G$bCx$7$/4sM?$9$k5-;v$N8l$H$$$C\e(B
 \e$B$7$g$K!"B>$N%P%C%U%!$KI=<($9$k$3$H$rB%$7$^$9!#\e(B
 
+Path \e$B$K\e(B @code{bogofilter} \e$B$N<B9T%U%!%$%k$,L5$$>l9g!"\e(BBogofilter \e$B$N=hM}$O\e(B
+\e$B<h$j>C$5$l$^$9!#\e(B
+
 @end defvar
 
 @end defvar
 
-@node Ifile spam filtering
-@subsubsection Ifile \e$B$K$h$k\e(B spam \e$B$N_I2a\e(B
+@defvar gnus-group-spam-exit-processor-bogofilter
+\e$B$3$N%7%s%\%k$r!"%0%k!<%W%Q%i%a!<%?$N%+%9%?%^%$%:$K$h$C$F%0%k!<%W\e(B
+\e$B$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($k$+!"$^$?\e(B
+\e$B$O\e(B @code{gnus-spam-process-newsgroups} \e$BJQ?t$K2C$($F2<$5$$!#$3$N%7%s%\%k\e(B
+\e$B$,%0%k!<%W$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($i$l$k$H!"\e(Bspam \e$B0u$,IU$$\e(B
+\e$B$?5-;v$,\e(B bogofilter \e$B$N\e(B spam \e$B%G!<%?%Y!<%9$K2C$($i$l!"\e(Bham \e$B0u$,IU$$$?5-;v\e(B
+\e$B$,\e(B bogofilter \e$B$N\e(B ham \e$B%G!<%?%Y!<%9$K2C$($i$l$^$9!#\e(B
+@strong{Bogofilter \e$B$N\e(B spam \e$B%W%m%;%C%5!<$O!"$5$i$K\e(B ham \e$B=hM}$b9T$J$&$?$@0l\e(B
+\e$B$D$N\e(B spam \e$B%W%m%;%C%5!<$G$"$k$3$H$KCm0U$7$F2<$5$$!#\e(B}
+@end defvar
+
+@node ifile spam filtering
+@subsubsection ifile \e$B$K$h$k\e(B spam \e$B$N_I2a\e(B
 @cindex spam filtering
 @cindex ifile, spam filtering
 @cindex spam.el
 
 @defvar spam-use-ifile
 
 @cindex spam filtering
 @cindex ifile, spam filtering
 @cindex spam.el
 
 @defvar spam-use-ifile
 
-Bogofilter \e$B$K;w$?E}7WJ,@O4o$G$"$k\e(B Ifile \e$B$r;H$$$?$$>l9g$O!"$3$NJQ?t$rM-8z\e(B
-\e$B$K$7$F2<$5$$!#:#$N$H$3$m\e(B @code{ifile-gnus.el} \e$B$r\e(B load \e$B$7$J$1$l$P$J$j$^$;\e(B
-\e$B$s!#\e(BIfile \e$B$N\e(B @code{spam.el} \e$B$X$NE}9g$O$^$@:Q$s$G$$$^$;$s$,!"$=$l$r9%$`$J\e(B
-\e$B$i$P\e(B @code{ifile-gnus.el} \e$B$rC1FH$K;H$&$3$H$,$G$-$^$9!#\e(B
+Bogofilter \e$B$K;w$?E}7WJ,@O4o$G$"$k\e(B ifile \e$B$r\e(B @code{spam-split} \e$B$K;H$$$?$$\e(B
+\e$B>l9g$O!"$3$NJQ?t$rM-8z$K$7$F2<$5$$!#\e(B
+
+@end defvar
+
+@defvar spam-ifile-all-categories
+
+@code{spam-use-ifile} \e$B$K!"C1$J$k\e(B smap/\e$BHs\e(B-spam \e$B$G$O$J$/$F\e(B ifile \e$B$N$9$Y$F\e(B
+\e$B$N%+%F%4%j!<$rM?$($F$b$i$$$?$$$J$i$P!"$3$NJQ?t$rM-8z$K$7$F2<$5$$!#$3$l$r\e(B
+\e$B;H$&>l9g$O!"$=$NJ88%$K=q$+$l$F$$$k$h$&$K\e(B ifile \e$B$r71N}$7$F$*$+$J$1$l$P$J\e(B
+\e$B$j$^$;$s!#\e(B
+
+@end defvar
+
+@defvar spam-ifile-spam-category
+
+ifile \e$B$K4X$9$k8B$j!"$3$l$O\e(B spam \e$B%a%C%;!<%8$N%+%F%4%j!<$G$9!#<B:]$K;H$o$l\e(B
+\e$B$kJ8;zNs$OL54X78$G$9$,!"$?$V$s$"$J$?$O\e(B @samp{spam} \e$B$NCM$r;D$7$F$*$-$?$$\e(B
+\e$B$G$7$g$&!#\e(B
+@end defvar
+
+@defvar spam-ifile-database-path
+
+\e$B$3$l$O\e(B ifile \e$B%G!<%?%Y!<%9$N%U%!%$%kL>$G$9!#%G%#%U%)%k%H$G$ODj5A$5$l$F$$\e(B
+\e$B$J$$$N$G!"\e(Bifile \e$B$O$=$l<+?H$N%G%#%U%)%k%H$N%G!<%?%Y!<%9L>$r;H$$$^$9!#\e(B
+
+@end defvar
+
+ifile \e$B$N%a!<%kJ,N`4o$O!"0U?^$HL\E*$NE@$G\e(B Bogofilter \e$B$K;w$F$$$^$9!#\e(B
+Spam \e$B$H\e(B ham \e$B$N%W%m%;%C%5!<!"$=$l$K\e(B spam-\e$BJ,3d\e(B (spam-split) \e$B$K\e(B ifile \e$B$,;H\e(B
+\e$B$o$l$k$Y$-$G$"$k$3$H$r<($9\e(B @code{spam-use-ifile} \e$BJQ?t$rDs6!$7$^$9!#$3$N\e(B
+\e$B5!G=$r8!::$9$k$?$a$K\e(B ifile \e$B$N%P!<%8%g%s\e(B 1.2.1 \e$B$,;H$o$l$^$7$?!#\e(B
+
+@node spam-stat spam filtering
+@subsubsection spam-\e$BE}7W\e(B (spam-stat) \e$B$K$h$k\e(B spam \e$B$N_I2a\e(B
+@cindex spam filtering
+@cindex spam-stat, spam filtering
+@cindex spam-stat.el
+@cindex spam.el
+
+@xref{Filtering Spam Using Statistics (spam-stat.el)}.
+
+@defvar spam-use-stat
+
+Emacs Lisp \e$B$K$h$kE}7WJ,@O4o$G$"$k\e(B spam-stat.el \e$B$r\e(B @code{spam-split} \e$B$K;H\e(B
+\e$B$o$;$?$$$J$i$P!"$3$NJQ?t$rM-8z$K$7$F2<$5$$!#\e(B
 
 @end defvar
 
 
 @end defvar
 
+@defvar gnus-group-spam-exit-processor-stat
+\e$B$3$N%7%s%\%k$r!"%0%k!<%W%Q%i%a!<%?$N%+%9%?%^%$%:$K$h$C$F%0%k!<%W\e(B
+\e$B$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($k$+!"$^$?\e(B
+\e$B$O\e(B @code{gnus-spam-process-newsgroups} \e$BJQ?t$K2C$($F2<$5$$!#$3$N%7%s%\%k\e(B
+\e$B$,%0%k!<%W$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($i$l$k$H!"\e(Bspam \e$B0u$,IU$$\e(B
+\e$B$?5-;v$,\e(B spam \e$B5-;vMQ$N\e(B spam-stat \e$B%G!<%?%Y!<%9$KDI2C$5$l$^$9!#\e(B
+@end defvar
+
+@defvar gnus-group-ham-exit-processor-stat
+\e$B$3$N%7%s%\%k$r!"%0%k!<%W%Q%i%a!<%?$N%+%9%?%^%$%:$K$h$C$F%0%k!<%W\e(B
+\e$B$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($k$+!"$^$?\e(B
+\e$B$O\e(B @code{gnus-spam-process-newsgroups} \e$BJQ?t$K2C$($F2<$5$$!#$3$N%7%s%\%k\e(B
+\e$B$,%0%k!<%W$N\e(B @code{spam-process} \e$B%Q%i%a!<%?$K2C$($i$l$k$H!"\e(Bham \e$B0u$,IU$$\e(B
+\e$B$?\e(B @emph{ham} \e$B%0%k!<%W$N5-;v$,Hs\e(B-spam \e$B5-;vMQ$N\e(B spam-stat \e$B%G!<%?%Y!<%9$K\e(B
+\e$BDI2C$5$l$^$9!#$3$N\e(B ham \e$B%W%m%;%C%5!<$O\e(B @emph{spam} \e$B$+\e(B @emph{\e$BL$J,N`\e(B} \e$B%0%k!<\e(B
+\e$B%W$K$O8z2L$r5Z$\$5$J$$$3$H$KCm0U$7$F2<$5$$!#\e(B
+@end defvar
+
+\e$B$3$l$O\e(B spam.el \e$B$,\e(B spam-stat.el \e$B$HF/$-9g$&$3$H$r2DG=$K$7$^$9!#\e(B
+spam-stat.el \e$B$O\e(B (Lisp \e$B$@$1$N\e(B) spam \e$BFbIt%G!<%?%Y!<%9$rDs6!$7$^$9$,!"$=$l\e(B
+\e$B$O\e(B ifile \e$B$d\e(B Bogofilter \e$B$H0c$C$F30It%W%m%0%i%`$rI,MW$H$7$^$;$s!#\e(B
+Spam \e$B$H\e(B ham \e$B$N%W%m%;%C%5!<$H\e(B @code{spam-split} \e$B$N$?$a\e(B
+\e$B$N\e(B @code{spam-use-stat} \e$BJQ?t$,Ds6!$5$l$^$9!#\e(B
+
 @node Extending spam.el
 @subsubsection spam.el \e$B$N3HD%\e(B
 @cindex spam filtering
 @cindex spam.el, extending
 @cindex extending spam.el
 
 @node Extending spam.el
 @subsubsection spam.el \e$B$N3HD%\e(B
 @cindex spam filtering
 @cindex spam.el, extending
 @cindex extending spam.el
 
-\e$B?7$7$$%P%C%/%(%s%I\e(B blackbox \e$B$rDI2C$7$?$$$"$J$?$O!"0J2<$rMQ0U$7$F2<$5$$\e(B:
+\e$B?7$7$$%P%C%/%(%s%I\e(B blackbox \e$B$rDI2C$7$?$$$"$J$?$O!"F~$C$F$/$k%a!<%k$r_I2a\e(B
+\e$B$9$k$?$a$K0J2<$rMQ0U$7$F2<$5$$\e(B:
 
 @enumerate
 
 @enumerate
-@item
-\e$B@bL@J8\e(B
 
 @item
 \e$B%3!<%I\e(B
 
 @item
 \e$B%3!<%I\e(B
@@ -21126,7 +21349,7 @@ Bogofilter \e$B$K;w$?E}7WJ,@O4o$G$"$k\e(B Ifile \e$B$r;H$$$?$$>l9g$O!"$3$NJQ?t$rM-8
   "Blackbox \e$B$r;H$&$H$-$O\e(B t \e$B$K$9$k!#\e(B")
 @end example
 
   "Blackbox \e$B$r;H$&$H$-$O\e(B t \e$B$K$9$k!#\e(B")
 @end example
 
-@code{spam-list-of-checks} \e$B$K\e(B 
+@code{spam-list-of-checks} \e$B$K\e(B
 @example
     (spam-use-blackbox  . spam-check-blackbox)
 @end example
 @example
     (spam-use-blackbox  . spam-check-blackbox)
 @end example
@@ -21140,6 +21363,62 @@ Bogofilter \e$B$K;w$?E}7WJ,@O4o$G$"$k\e(B Ifile \e$B$r;H$$$?$$>l9g$O!"$3$NJQ?t$rM-8
 \e$B$?$K$G$-$k$3$H$NNc$O!"4{B8$N\e(B @code{spam-check-*} \e$B4X?t$r;2>H$7$F$/$@$5$$!#\e(B
 @end enumerate
 
 \e$B$?$K$G$-$k$3$H$NNc$O!"4{B8$N\e(B @code{spam-check-*} \e$B4X?t$r;2>H$7$F$/$@$5$$!#\e(B
 @end enumerate
 
+Spam \e$B$H\e(B ham \e$B%a%C%;!<%8$r=hM}$9$k$K$O!"0J2<$rMQ0U$7$F2<$5$$\e(B:
+
+@enumerate
+
+@item
+\e$B%3!<%I\e(B
+
+Spam \e$B$^$?$O\e(B ham \e$B$N%W%m%;%C%5!<$rMQ0U$9$kI,MW$O$"$j$^$;$s!#\e(B
+Blackbox \e$B$,\e(B spam \e$B$^$?$O\e(B ham \e$B$N=hM}$r%5%]!<%H$9$k>l9g$@$1!"$=$l$i$rMQ0U$7\e(B
+\e$B$F2<$5$$!#\e(B
+
+@example
+(defvar gnus-group-spam-exit-processor-blackbox "blackbox"
+  "\e$B35N,$r=P$k$H$-$K8F$P$l$k\e(B blackbox \e$B$N\e(B spam \e$B%W%m%;%C%5!<!#\e(B
+Spam \e$B%0%k!<%W$@$1$KE,MQ$5$l$k!#\e(B")
+
+(defvar gnus-group-ham-exit-processor-blackbox "blackbox"
+  "\e$B35N,$r=P$k$H$-$K8F$P$l$k\e(B blackbox \e$B$N\e(B ham \e$B%W%m%;%C%5!<!#\e(B
+Spam \e$B$G$O$J$$\e(B (\e$BL$J,N`$^$?$O\e(B ham) \e$B%0%k!<%W$@$1$KE,MQ$5$l$k!#\e(B")
+
+@end example
+
+@item
+\e$B4X?t\e(B
+
+@example
+(defun spam-blackbox-register-spam-routine ()
+  (spam-generic-register-routine
+   ;; spam \e$BMQ$N4X?t\e(B
+   (lambda (article)
+     (let ((from (spam-fetch-field-from-fast article)))
+       (when (stringp from)
+          (blackbox-do-something-with-this-spammer from))))
+   ;; ham \e$BMQ$N4X?t\e(B
+   nil))
+
+(defun spam-blackbox-register-ham-routine ()
+  (spam-generic-register-routine
+   ;; spam \e$BMQ$N4X?t\e(B
+   nil
+   ;; ham \e$BMQ$N4X?t\e(B
+   (lambda (article)
+     (let ((from (spam-fetch-field-from-fast article)))
+       (when (stringp from)
+          (blackbox-do-something-with-this-ham-sender from))))))
+@end example
+
+\e$B4X?t\e(B @code{blackbox-do-something-with-this-ham-sender} \e$B$*$h\e(B
+\e$B$S\e(B @code{blackbox-do-something-with-this-spammer} \e$B$r=q$$$F2<$5$$!#%a%C%;!<\e(B
+\e$B%8$NAw?.<T$r<h$j=P$9$h$j$bJ#;($J%3!<%I$rDI2C$9$k$3$H$O2DG=$G$9$,!"%a%C%;!<\e(B
+\e$B%8A4BN$N<h$j9~$_$O!"\e(B@code{spam-fetch-field-from-fast} \e$B$GAw?.<T$r<h$j=P\e(B
+\e$B$9\e(B (\e$B%a%C%;!<%8$NAw?.<T$O\e(B gnus \e$B$K$h$C$F5-21$5$l$F$$$k\e(B) \e$B$h$j$bCx$7$/D9$/$+\e(B
+\e$B$+$k$3$H$r3P$($F$*$$$F2<$5$$!#\e(B
+
+@end enumerate
+
 @node Filtering Spam Using Statistics (spam-stat.el)
 @subsection Spam \e$B$N_I2a$KE}7W$r;H$&\e(B (spam-stat.el)
 @cindex Paul Graham
 @node Filtering Spam Using Statistics (spam-stat.el)
 @subsection Spam \e$B$N_I2a$KE}7W$r;H$&\e(B (spam-stat.el)
 @cindex Paul Graham
@@ -21163,7 +21442,7 @@ Paul Graham \e$B$O!"E}7W$r;H$C$?\e(B spam \e$B$N_I2a$K4X$9$kM%$l$?%(%C%;%$$r=q$-$^$
 \e$B$O\e(B spam\e$B!"$b$&0l$D$OHs\e(B-spam \e$B$G!#N>J}$N%3%l%/%7%g%s$K$*$1$k3FC18l$N=P8=IQ\e(B
 \e$BEY$r?t$($F!"%3%l%/%7%g%s$N%a!<%k$NAm?t$G=E$_IU$1$r9T$J$$!"$3$N>pJs$r<-=q\e(B
 \e$B$K3JG<$7$^$9!#?7Ce%a!<%k$N$9$Y$F$NC18l$K$D$$$F!"\e(Bspam \e$B$+Hs\e(B-spam \e$B%a!<%k$K\e(B
 \e$B$O\e(B spam\e$B!"$b$&0l$D$OHs\e(B-spam \e$B$G!#N>J}$N%3%l%/%7%g%s$K$*$1$k3FC18l$N=P8=IQ\e(B
 \e$BEY$r?t$($F!"%3%l%/%7%g%s$N%a!<%k$NAm?t$G=E$_IU$1$r9T$J$$!"$3$N>pJs$r<-=q\e(B
 \e$B$K3JG<$7$^$9!#?7Ce%a!<%k$N$9$Y$F$NC18l$K$D$$$F!"\e(Bspam \e$B$+Hs\e(B-spam \e$B%a!<%k$K\e(B
-\e$BB0$9$k3NN($r7hDj$7$^$9!#\e(B15\e$B$N:G$b82Cx$JC18l$r;H$C$F!"$=$N%a!<%k\e(B
+\e$BB0$9$k3NN($r7hDj$7$^$9!#\e(B15 \e$B$N:G$b82Cx$JC18l$r;H$C$F!"$=$N%a!<%k\e(B
 \e$B$,\e(B spam \e$B$G$"$k$3$H$N3NN($NAm7W$r7W;;$7$^$9!#$3$N3NN($,$"$kogCM$h$j9b$+$C\e(B
 \e$B$?$i!"$=$N%a!<%k$O\e(B spam \e$B$G$"$k$H9M$($i$l$^$9!#\e(B
 
 \e$B$,\e(B spam \e$B$G$"$k$3$H$N3NN($NAm7W$r7W;;$7$^$9!#$3$N3NN($,$"$kogCM$h$j9b$+$C\e(B
 \e$B$?$i!"$=$N%a!<%k$O\e(B spam \e$B$G$"$k$H9M$($i$l$^$9!#\e(B
 
@@ -21180,7 +21459,7 @@ gnus \e$B$O$3$N<o$N_I2a$r%5%]!<%H$7$^$9!#$7$+$7$=$l$K$O$$$/$D$+$N@_Dj$,I,MW\e(B
 @end menu
 
 @node Creating a spam-stat dictionary
 @end menu
 
 @node Creating a spam-stat dictionary
-@subsubsection spam-stat \e$B<-=q$r:n$k\e(B
+@subsubsection spam-\e$BE}7W\e(B (spam-stat) \e$B<-=q$r:n$k\e(B
 
 \e$BE}7W$K4p$E$$$?\e(B spam \e$B_I2a$r;O$a$k$K$O!"$"$J$?$OFs$D$N%a!<%k$N%3%l%/%7%g%s\e(B
 \e$B$K4p$E$$$?E}7W$r:n$i$J$1$l$P$J$j$^$;$s!#0l$D$O\e(B spam \e$B$b$&0l$D$OHs\e(B-spam \e$B$G!#\e(B
 
 \e$BE}7W$K4p$E$$$?\e(B spam \e$B_I2a$r;O$a$k$K$O!"$"$J$?$OFs$D$N%a!<%k$N%3%l%/%7%g%s\e(B
 \e$B$K4p$E$$$?E}7W$r:n$i$J$1$l$P$J$j$^$;$s!#0l$D$O\e(B spam \e$B$b$&0l$D$OHs\e(B-spam \e$B$G!#\e(B
@@ -21209,25 +21488,30 @@ nnml \e$B%P%C%/%(%s%I$O0lDL$N%a!<%k$K$D$-0l$D$N%U%!%$%k$G!"$9$Y$F$N%a!<%k$r\e(B
 \e$B>o\e(B @samp{nnml:mail.misc} \e$B%0%k!<%W$KBP1~\e(B) \e$B$KBP$7\e(B
 \e$B$F\e(B @code{spam-stat-process-non-spam-directory} \e$B$r8F$V$G$7$g$&!#\e(B
 
 \e$B>o\e(B @samp{nnml:mail.misc} \e$B%0%k!<%W$KBP1~\e(B) \e$B$KBP$7\e(B
 \e$B$F\e(B @code{spam-stat-process-non-spam-directory} \e$B$r8F$V$G$7$g$&!#\e(B
 
+\e$B$"$J$?$,\e(B IMAP \e$B$r;H$C$F$$$k$J$i%a!<%k$r%m!<%+%k$K$O;}$C$F$$$J$$$N$G!"$=$l\e(B
+\e$B$OF0$+$J$$$G$7$g$&!#0l$D$N2r7h:v$O!"\e(Bgnus \e$B%(!<%8%'%s%H$G5-;v$r%-%c%C%7%e\e(B
+\e$B$9$k$3$H$G$9!#$=$&$9$l$P\e(B @code{spam-stat-process-spam-directory} \e$B$H$7\e(B
+\e$B$F\e(B @file{"~/News/agent/nnimap/mail.yourisp.com/personal_spam"} \e$B$N$h$&$J\e(B
+\e$B$b$N$,;H$($^$9!#\e(B@xref{Agent as Cache}\e$B!#\e(B
+
 @defvar spam-stat
 \e$B$3$NJQ?t$O$9$Y$F$NE}7W$N%O%C%7%e%F!<%V%k\e(B -- \e$B2f!9$,<-=q$H8@$C$F$$$k$b\e(B
 \e$B$N\e(B -- \e$B$r;}$A$^$9!#$3$N%O%C%7%e%F!<%V%k$O!"APJ}$N%3%l%/%7%g%s$N$9$Y$F$NC1\e(B
 \e$B8l$K$D$$$F\e(B spam \e$B$*$h$SHs\e(B-spam \e$B%a!<%k$K$*$1$k=P8=IQEY$rI=$9%Y%/%H%k$r3JG<\e(B
 \e$B$7$^$9!#\e(B
 @defvar spam-stat
 \e$B$3$NJQ?t$O$9$Y$F$NE}7W$N%O%C%7%e%F!<%V%k\e(B -- \e$B2f!9$,<-=q$H8@$C$F$$$k$b\e(B
 \e$B$N\e(B -- \e$B$r;}$A$^$9!#$3$N%O%C%7%e%F!<%V%k$O!"APJ}$N%3%l%/%7%g%s$N$9$Y$F$NC1\e(B
 \e$B8l$K$D$$$F\e(B spam \e$B$*$h$SHs\e(B-spam \e$B%a!<%k$K$*$1$k=P8=IQEY$rI=$9%Y%/%H%k$r3JG<\e(B
 \e$B$7$^$9!#\e(B
+@end defvar
 
 \e$BE}7W$r:G=i$+$i:n$jD>$7$?$$$H$-$O!"<-=q$r%j%;%C%H$9$kI,MW$,$"$j$^$9!#\e(B
 
 
 \e$BE}7W$r:G=i$+$i:n$jD>$7$?$$$H$-$O!"<-=q$r%j%;%C%H$9$kI,MW$,$"$j$^$9!#\e(B
 
-@end defvar
-
 @defun spam-stat-reset
 @code{spam-stat} \e$B%O%C%7%e%F!<%V%k$r%j%;%C%H$7!"$9$Y$F$NE}7W$r:o=|$7$^$9!#\e(B
 @defun spam-stat-reset
 @code{spam-stat} \e$B%O%C%7%e%F!<%V%k$r%j%;%C%H$7!"$9$Y$F$NE}7W$r:o=|$7$^$9!#\e(B
+@end defun
 
 \e$B9T$J$C$?$i<-=q$r%;!<%V$7$J$1$l$P$J$j$^$;$s!#<-=q$O$+$J$jBg$-$/$J$k$+$b$7\e(B
 \e$B$l$^$;$s!#<-=q$rDI2C99?7$7$J$$>l9g\e(B (\e$B8@$$49$($k$H!"Nc$($PKh7n0l2s:n$jD>$9\e(B
 \e$B>l9g\e(B)\e$B!"IQHK$K8=$l$J$$$+!"$^$?$O\e(B spam \e$B$+Hs\e(B-spam \e$B$N$I$A$i$KB0$9$k$+$,$O$C\e(B
 \e$B$-$j$7$J$$$9$Y$F$NC18l$r:o=|$9$k$3$H$K$h$C$F!"<-=q$N%5%$%:$r>.$5$/$9$k$3\e(B
 \e$B$H$,$G$-$^$9!#\e(B
 
 \e$B9T$J$C$?$i<-=q$r%;!<%V$7$J$1$l$P$J$j$^$;$s!#<-=q$O$+$J$jBg$-$/$J$k$+$b$7\e(B
 \e$B$l$^$;$s!#<-=q$rDI2C99?7$7$J$$>l9g\e(B (\e$B8@$$49$($k$H!"Nc$($PKh7n0l2s:n$jD>$9\e(B
 \e$B>l9g\e(B)\e$B!"IQHK$K8=$l$J$$$+!"$^$?$O\e(B spam \e$B$+Hs\e(B-spam \e$B$N$I$A$i$KB0$9$k$+$,$O$C\e(B
 \e$B$-$j$7$J$$$9$Y$F$NC18l$r:o=|$9$k$3$H$K$h$C$F!"<-=q$N%5%$%:$r>.$5$/$9$k$3\e(B
 \e$B$H$,$G$-$^$9!#\e(B
-@end defun
 
 @defun spam-stat-reduce-size
 \e$B<-=q$N%5%$%:$r>.$5$/$7$^$9!#$3$l$O<-=q$rDI2C99?7$7$?$/$J$$>l9g$@$1;H$C$F\e(B
 
 @defun spam-stat-reduce-size
 \e$B<-=q$N%5%$%:$r>.$5$/$7$^$9!#$3$l$O<-=q$rDI2C99?7$7$?$/$J$$>l9g$@$1;H$C$F\e(B
@@ -21244,7 +21528,7 @@ nnml \e$B%P%C%/%(%s%I$O0lDL$N%a!<%k$K$D$-0l$D$N%U%!%$%k$G!"$9$Y$F$N%a!<%k$r\e(B
 @end defvar
 
 @node Splitting mail using spam-stat
 @end defvar
 
 @node Splitting mail using spam-stat
-@subsubsection spam-stat \e$B$r;H$C$F%a!<%k$rJ,3d$9$k\e(B
+@subsubsection spam-\e$BE}7W\e(B (spam-stat) \e$B$r;H$C$F%a!<%k$rJ,3d$9$k\e(B
 
 @code{spam-stat} \e$B$r;H$C$F%a!<%k$rJ,3d$9$k$?$a$K!"\e(B@file{~/.gnus} \e$B%U%!%$%k\e(B
 \e$B$K0J2<$rDI2C$9$kI,MW$,$"$j$^$9!#\e(B
 
 @code{spam-stat} \e$B$r;H$C$F%a!<%k$rJ,3d$9$k$?$a$K!"\e(B@file{~/.gnus} \e$B%U%!%$%k\e(B
 \e$B$K0J2<$rDI2C$9$kI,MW$,$"$j$^$9!#\e(B
@@ -21257,9 +21541,13 @@ nnml \e$B%P%C%/%(%s%I$O0lDL$N%a!<%k$K$D$-0l$D$N%U%!%$%k$G!"$9$Y$F$N%a!<%k$r\e(B
 \e$B$3$l$OI,MW$J\e(B gnus \e$B$N%3!<%I$H$"$J$?$,:n$C$?<-=q$r\e(B load \e$B$7$^$9!#\e(B
 
 \e$B<!$K!"FC5iJ,3d$N5,B'$rE,9g$5$;$kI,MW$,$"$j$^$9\e(B: \e$B$I$&$d$C\e(B
 \e$B$3$l$OI,MW$J\e(B gnus \e$B$N%3!<%I$H$"$J$?$,:n$C$?<-=q$r\e(B load \e$B$7$^$9!#\e(B
 
 \e$B<!$K!"FC5iJ,3d$N5,B'$rE,9g$5$;$kI,MW$,$"$j$^$9\e(B: \e$B$I$&$d$C\e(B
-\e$B$F\e(B @code{spam-stat} \e$B$r;H$&$+$r7h$a$F2<$5$$!#$G\e(B
-\e$B$O\e(B @samp{mail.misc} \e$B$H\e(B @samp{mail.spam} \e$B$NFs$D$N%0%k!<%W$@$1$,$"$k:G$bC1\e(B
-\e$B=c$J;vNc$G$O$I$&$J$k$+!#0J2<$N<0$O%a!<%k$,\e(B spam \e$B$G$"$k$+!"$^$?$O$=$l\e(B
+\e$B$F\e(B @code{spam-stat} \e$B$r;H$&$+$r7h$a$F2<$5$$!#0J2<$NNc$O\e(B nnml \e$B%P%C%/%(%s%I\e(B
+\e$BMQ$G$9!#\e(Bnnimap \e$B%P%C%/%(%s%I$G$b$^$C$?$/F1MM$KF0:n$7$^$9!#C1\e(B
+\e$B$K\e(B @code{nnmail-split-fancy} \e$B$NBe$o$j$K\e(B @code{nnimap-split-fancy} \e$B$r;H$C\e(B
+\e$B$F2<$5$$!#\e(B
+
+\e$B$G$O\e(B @samp{mail.misc} \e$B$H\e(B @samp{mail.spam} \e$B$NFs$D$N%0%k!<%W$@$1$,$"$k:G$b\e(B
+\e$BC1=c$J;vNc$G$O$I$&$J$k$+!#0J2<$N<0$O%a!<%k$,\e(B spam \e$B$G$"$k$+!"$^$?$O$=$l\e(B
 \e$B$,\e(B @samp{mail.misc} \e$B$K9T$/$Y$-$@$H8@$C$F$$$^$9!#$b$7\e(B spam \e$B$@$C$?\e(B
 \e$B$i\e(B @code{spam-stat-split-fancy} \e$B$O\e(B @samp{mail.spam} \e$B$rJV$7$^$9!#\e(B
 
 \e$B$,\e(B @samp{mail.misc} \e$B$K9T$/$Y$-$@$H8@$C$F$$$^$9!#$b$7\e(B spam \e$B$@$C$?\e(B
 \e$B$i\e(B @code{spam-stat-split-fancy} \e$B$O\e(B @samp{mail.spam} \e$B$rJV$7$^$9!#\e(B
 
@@ -21313,71 +21601,64 @@ Spam \e$BMQ$N%0%k!<%W$G$9!#%G%#%U%)%k%H$O\e(B @samp{mail.spam} \e$B$G$9!#\e(B
 @end example
 
 @node Low-level interface to the spam-stat dictionary
 @end example
 
 @node Low-level interface to the spam-stat dictionary
-@subsubsection spam-stat \e$B<-=q$X$NDc3,AX%$%s%?!<%U%'!<%9\e(B
+@subsubsection spam-\e$BE}7W\e(B (spam-stat) \e$B<-=q$X$NDc3,AX%$%s%?!<%U%'!<%9\e(B
 
 @code{spam-stat} \e$B$r;H$&$?$a$N<g%$%s%?!<%U%'!<%9$O0J2<$N4X?t$G$9\e(B:
 
 @defun spam-stat-buffer-is-spam
 
 @code{spam-stat} \e$B$r;H$&$?$a$N<g%$%s%?!<%U%'!<%9$O0J2<$N4X?t$G$9\e(B:
 
 @defun spam-stat-buffer-is-spam
-Spam \e$B$G$"$k$H9M$($i$l$k?7Ce%a!<%k$,$"$k%P%C%U%!$G8F$P$l$^$9\e(B; \e$B=hM}A0$N?7\e(B
+Spam \e$B$G$"$k$H9M$($i$l$k?7Ce%a!<%k$,$"$k%P%C%U%!$G8F$P$l$^$9!#=hM}A0$N?7\e(B
 \e$BCe%a!<%k$KBP$7$F;H$C$F2<$5$$!#\e(B
 \e$BCe%a!<%k$KBP$7$F;H$C$F2<$5$$!#\e(B
-
 @end defun
 
 @defun spam-stat-buffer-is-no-spam
 @end defun
 
 @defun spam-stat-buffer-is-no-spam
-\e$BHs\e(B-spam \e$B$G$"$k$H9M$($i$l$k?7Ce%a!<%k$,$"$k%P%C%U%!$G8F$P$l$^$9\e(B; \e$B=hM}A0$N\e(B
+\e$BHs\e(B-spam \e$B$G$"$k$H9M$($i$l$k?7Ce%a!<%k$,$"$k%P%C%U%!$G8F$P$l$^$9!#=hM}A0$N\e(B
 \e$B?7Ce%a!<%k$KBP$7$F;H$C$F2<$5$$!#\e(B
 \e$B?7Ce%a!<%k$KBP$7$F;H$C$F2<$5$$!#\e(B
-
 @end defun
 
 @defun spam-stat-buffer-change-to-spam
 Spam \e$B$G$O$J$$DL>o$N%a!<%k$@$H$O$b$O$d9M$($i$l$J$$%a!<%k$,$"$k%P%C%U%!$G\e(B
 @end defun
 
 @defun spam-stat-buffer-change-to-spam
 Spam \e$B$G$O$J$$DL>o$N%a!<%k$@$H$O$b$O$d9M$($i$l$J$$%a!<%k$,$"$k%P%C%U%!$G\e(B
-\e$B8F$P$l$^$9\e(B; \e$B$9$G$KHs\e(B-spam \e$B$G$"$k$b$N$H$7$F=hM}$5$l$F$7$^$C$?%a!<%k$NCO0L\e(B
+\e$B8F$P$l$^$9!#$9$G$KHs\e(B-spam \e$B$G$"$k$b$N$H$7$F=hM}$5$l$F$7$^$C$?%a!<%k$NCO0L\e(B
 \e$B$NJQ99$K;H$C$F2<$5$$!#\e(B
 \e$B$NJQ99$K;H$C$F2<$5$$!#\e(B
-
 @end defun
 
 @defun spam-stat-buffer-change-to-non-spam
 \e$BDL>o$N%a!<%k$G$O$J$$\e(B spam \e$B$@$H$O$b$O$d9M$($i$l$J$$%a!<%k$,$"$k%P%C%U%!$G\e(B
 @end defun
 
 @defun spam-stat-buffer-change-to-non-spam
 \e$BDL>o$N%a!<%k$G$O$J$$\e(B spam \e$B$@$H$O$b$O$d9M$($i$l$J$$%a!<%k$,$"$k%P%C%U%!$G\e(B
-\e$B8F$P$l$^$9\e(B; \e$B$9$G$K\e(B spam \e$B$G$"$k$b$N$H$7$F=hM}$5$l$F$7$^$C$?%a!<%k$NCO0L$N\e(B
+\e$B8F$P$l$^$9!#$9$G$K\e(B spam \e$B$G$"$k$b$N$H$7$F=hM}$5$l$F$7$^$C$?%a!<%k$NCO0L$N\e(B
 \e$BJQ99$K;H$C$F2<$5$$!#\e(B
 \e$BJQ99$K;H$C$F2<$5$$!#\e(B
-
 @end defun
 
 @defun spam-stat-save
 @end defun
 
 @defun spam-stat-save
-\e$B%O%C%7%e%F!<%V%k$r%U%!%$%k$K%;!<%V$7$^$9\e(B; \e$BJQ?t\e(B @code{spam-stat-file} \e$B$G\e(B
+\e$B%O%C%7%e%F!<%V%k$r%U%!%$%k$K%;!<%V$7$^$9!#JQ?t\e(B @code{spam-stat-file} \e$B$G\e(B
 \e$B@_Dj$5$l$?%U%!%$%kL>$,;H$o$l$^$9!#\e(B
 \e$B@_Dj$5$l$?%U%!%$%kL>$,;H$o$l$^$9!#\e(B
-
 @end defun
 
 @defun spam-stat-load
 @end defun
 
 @defun spam-stat-load
-\e$B%O%C%7%e%F!<%V%k$r%U%!%$%k$+$i\e(B load \e$B$7$^$9\e(B; \e$BJQ\e(B
+\e$B%O%C%7%e%F!<%V%k$r%U%!%$%k$+$i\e(B load \e$B$7$^$9!#JQ\e(B
 \e$B?t\e(B @code{spam-stat-file} \e$B$G@_Dj$5$l$?%U%!%$%kL>$,;H$o$l$^$9!#\e(B
 \e$B?t\e(B @code{spam-stat-file} \e$B$G@_Dj$5$l$?%U%!%$%kL>$,;H$o$l$^$9!#\e(B
-
 @end defun
 
 @defun spam-stat-score-word
 \e$BC18l$N\e(B spam \e$B%9%3%"$rJV$7$^$9!#\e(B
 @end defun
 
 @defun spam-stat-score-word
 \e$BC18l$N\e(B spam \e$B%9%3%"$rJV$7$^$9!#\e(B
-
 @end defun
 
 @defun spam-stat-score-buffer
 \e$B%P%C%U%!$N\e(B spam \e$B%9%3%"$rJV$7$^$9!#\e(B
 @end defun
 
 @defun spam-stat-score-buffer
 \e$B%P%C%U%!$N\e(B spam \e$B%9%3%"$rJV$7$^$9!#\e(B
-
 @end defun
 
 @defun spam-stat-split-fancy
 @end defun
 
 @defun spam-stat-split-fancy
-\e$BFC5i%a!<%kJ,3d$N$?$a$K!"\e(B@code{nnmail-split-fancy} \e$B$K5,\e(B
-\e$BB'\e(B @samp{(: spam-stat-split-fancy)} \e$B$rDI2C$7$^$9!#\e(B
+\e$BFC5i%a!<%kJ,3d$N$?$a$K$3$N4X?t$r;H$C$F2<$5$$!#\e(B
+@code{nnmail-split-fancy} \e$B$K5,B'\e(B @samp{(: spam-stat-split-fancy)} \e$B$rDI2C\e(B
+\e$B$7$^$9!#\e(B
+@end defun
 
 
-\e$B$3$l$K$O\e(B @file{~/.gnus} \e$B$K0J2<$,I,MW$G$9\e(B:
+\e$B$=$l$r;H$&A0$K!"I,$:<-=q$,\e(B load \e$B$5$l$F$$$k$h$&$K$7$F2<$5$$!#$3$l$K\e(B
+\e$B$O\e(B @file{~/.gnus} \e$B%U%!%$%k$K0J2<$,I,MW$G$9\e(B:
 
 @example
 (require 'spam-stat)
 (spam-stat-load)
 @end example
 
 
 @example
 (require 'spam-stat)
 (spam-stat-load)
 @end example
 
-@end defun
-
 \e$BBeI=E*$J%F%9%H$O0J2<$N4X?t8F=P$7$rI,MW$H$7$^$9\e(B:
 
 @example
 \e$BBeI=E*$J%F%9%H$O0J2<$N4X?t8F=P$7$rI,MW$H$7$^$9\e(B:
 
 @example
@@ -21589,15 +21870,15 @@ but at the common table.@*
 XEmacs \e$B$O%Q%C%1!<%8$N=/=8$H$7$FG[I[$5$l$F$$$^$9!#\e(Bgnus \e$B$N\e(B XEmacs \e$B%Q%C%1!<\e(B
 \e$B%8$,I,MW$H$9$k$b$N$O2?$G$"$l!"$"$J$?$O%$%s%9%H!<%k$9$Y$-$G$9!#:#$N$H$3$m\e(B
 \e$BI,MW$J$N$O\e(B @samp{gnus}, @samp{w3}, @samp{mh-e}, @samp{mailcrypt},
 XEmacs \e$B$O%Q%C%1!<%8$N=/=8$H$7$FG[I[$5$l$F$$$^$9!#\e(Bgnus \e$B$N\e(B XEmacs \e$B%Q%C%1!<\e(B
 \e$B%8$,I,MW$H$9$k$b$N$O2?$G$"$l!"$"$J$?$O%$%s%9%H!<%k$9$Y$-$G$9!#:#$N$H$3$m\e(B
 \e$BI,MW$J$N$O\e(B @samp{gnus}, @samp{w3}, @samp{mh-e}, @samp{mailcrypt},
-@samp{rmail}, @samp{eterm}, @samp{mail-lib}, @samp{xemacs-base} \e$B$*$h$S\e(B
-@samp{fsf-compat} \e$B$G$9!#%b!<%k%9I|9f$N$?$a$K$O\e(B @samp{misc-games} \e$B%Q%C%1!<\e(B
-\e$B%8$,I,MW$G$9!#\e(B
+@samp{rmail}, @samp{eterm}, @samp{mail-lib}, @samp{xemacs-base},
+@samp{sh-script} \e$B$*$h$S\e(B @samp{fsf-compat} \e$B$G$9!#%b!<%k%9I|9f$N$?$a$K\e(B
+\e$B$O\e(B @samp{misc-games} \e$B%Q%C%1!<%8$,I,MW$G$9!#\e(B
 
 @node History
 @section \e$BNr;K\e(B
 
 @cindex history
 
 @node History
 @section \e$BNr;K\e(B
 
 @cindex history
-@sc{gnus} \e$B$O\e(B \e$BG_ED\e(B \e$B@/?.;a$K$h$C$F=q$+$l$^$7$?!#\e(B94\e$BG/$N2F$,G&$S4s$C$F$/$k$3\e(B
+@sc{gnus} \e$B$OG_ED@/?.;a$K$h$C$F=q$+$l$^$7$?!#\e(B94\e$BG/$N2F$,G&$S4s$C$F$/$k$3\e(B
 \e$B$m!"\e(BLars Magne Ingebrigtsen \e$B$OK0$-$F$-$F!"\e(BGnus \e$B$r=q$-D>$=$&$H7h?4$7$^$7\e(B
 \e$B$?!#\e(B
 
 \e$B$m!"\e(BLars Magne Ingebrigtsen \e$B$OK0$-$F$-$F!"\e(BGnus \e$B$r=q$-D>$=$&$H7h?4$7$^$7\e(B
 \e$B$?!#\e(B
 
@@ -21909,8 +22190,8 @@ Gnus \e$B$OFs$D$NCJ3,$N=[4D$G3+H/$5$l$F$$$^$9!#:G=i$NCJ3,\e(B
 
 @cindex Incoming*
 @vindex mail-source-delete-incoming
 
 @cindex Incoming*
 @vindex mail-source-delete-incoming
-\e$B%"%k%U%!\e(B Gnusae \e$B$H\e(B \e$B%j%j!<%9$5$l$?\e(B Gnusae \e$B$G$OJQ?t$N=i4|CM$,0c$&$b$N$,$"\e(B
-\e$B$j$^$9!#FC$K!"\e(B@code{mail-source-delete-incoming} \e$B$O%"%k%U%!\e(B gnusae \e$B$G\e(B
+\e$B%"%k%U%!\e(B Gnusae \e$B$H%j%j!<%9$5$l$?\e(B Gnusae \e$B$G$OJQ?t$N=i4|CM$,0c$&$b$N$,$"$j\e(B
+\e$B$^$9!#FC$K!"\e(B@code{mail-source-delete-incoming} \e$B$O%"%k%U%!\e(B gnusae \e$B$G\e(B
 \e$B$O\e(B @code{nil} \e$B$G!"%j%j!<%9$5$l$?\e(B gnusae \e$B$G$O\e(B @code{t} \e$B$G$9!#$3$l$O%a!<%k\e(B
 \e$B$r07$C$F$$$k:]$K!"%"%k%U%!%j%j!<%9$Nsrsw$K$h$j%a!<%k$r<:$J$&$3$H$rHr$1$k\e(B
 \e$B$?$a$G$9!#\e(B
 \e$B$O\e(B @code{nil} \e$B$G!"%j%j!<%9$5$l$?\e(B gnusae \e$B$G$O\e(B @code{t} \e$B$G$9!#$3$l$O%a!<%k\e(B
 \e$B$r07$C$F$$$k:]$K!"%"%k%U%!%j%j!<%9$Nsrsw$K$h$j%a!<%k$r<:$J$&$3$H$rHr$1$k\e(B
 \e$B$?$a$G$9!#\e(B
@@ -21944,7 +22225,7 @@ Micro$oft---\e$B$"$!!#%"%^%A%e%"!#;d$O\e(B @emph{\e$B$b$C$H\e(B} \e$B0-$$!#\e(B(\e$B$b$
 @itemize @bullet
 
 @item
 @itemize @bullet
 
 @item
-\e$BG_ED\e(B \e$B@/?.\e(B---\e$B85$N\e(B @sc{gnus} \e$B$r=q$$$??M$G$9!#\e(B
+\e$BG_ED@/?.\e(B---\e$B85$N\e(B @sc{gnus} \e$B$r=q$$$??M$G$9!#\e(B
 
 @item
 Shenghuo Zhu---uudecode.el, mm-uu.el, rfc1843.el, webmail.el,
 
 @item
 Shenghuo Zhu---uudecode.el, mm-uu.el, rfc1843.el, webmail.el,
@@ -22321,7 +22602,7 @@ Gnus \e$B$OIaDL$N\e(B Emacs \e$B$NJ}K!$G<+F0J]B8$5$l$k%I%j%V%k%P%C%U%!$rJ];}$7$F$$$
 
 @item
 Gnus \e$B$O:#$d%U%!%$%k\e(B @file{.emacs} \e$B$r$0$A$c$0$A$c$K$9$k;v$rHr$1$k$?$a$K@l\e(B
 
 @item
 Gnus \e$B$O:#$d%U%!%$%k\e(B @file{.emacs} \e$B$r$0$A$c$0$A$c$K$9$k;v$rHr$1$k$?$a$K@l\e(B
-\e$BMQ$N5/F0%U%!%$%k\e(B (@file{.gnus}) \e$B$r;}$D$h$&$K$J$j$^$7$?!#\e(B
+\e$BMQ$N5/F0%U%!%$%k\e(B (@file{.gnus.el}) \e$B$r;}$D$h$&$K$J$j$^$7$?!#\e(B
 
 @item
 \e$B%0%k!<%W$H5-;v$NN>J}$K%W%m%;%90u$rIU$1$k$3$H$,$G$-!"A4$F$N0u$NIU$$$?9`L\\e(B
 
 @item
 \e$B%0%k!<%W$H5-;v$NN>J}$K%W%m%;%90u$rIU$1$k$3$H$,$G$-!"A4$F$N0u$NIU$$$?9`L\\e(B
@@ -23106,7 +23387,7 @@ gnus \e$B$O4pK\E*$J%a%G%#%"$r07$$$^$;$s!#$9$Y$F$O%P%C%/%(%s%I$K$h$C$F9T$J$o\e(B
 @item \e$B4pK\\e(B (native)
 @cindex native
 Gnus \e$B$O$$$D$b0l$D$NJ}K!\e(B (\e$B$H%P%C%/%(%s%I\e(B) \e$B$r%K%e!<%9$rF@$k$?$a$N\e(B @dfn{\e$B4p\e(B
 @item \e$B4pK\\e(B (native)
 @cindex native
 Gnus \e$B$O$$$D$b0l$D$NJ}K!\e(B (\e$B$H%P%C%/%(%s%I\e(B) \e$B$r%K%e!<%9$rF@$k$?$a$N\e(B @dfn{\e$B4p\e(B
-\e$BK\\e(B} \e$B$b$7$/$O=i4|@_Dj\e(B \e$B$H$7$F;H$$$^$9!#\e(B
+\e$BK\\e(B} \e$B$b$7$/$O=i4|@_Dj$H$7$F;H$$$^$9!#\e(B
 
 @item \e$B30It\e(B (foreign)
 @cindex foreign
 
 @item \e$B30It\e(B (foreign)
 @cindex foreign
@@ -24115,6 +24396,9 @@ description-buffer = *description-line
 \e$B$3$N4X?t$O!"%0%k!<%WL>$,\e(B @code{car} \e$B$G!"$=$N5-;v$N0\F0@h$N5-;vHV9f$,\e(B
 @code{cdr} \e$B$G$"$k\e(B cons \e$B%;%k$rJV$7$^$9!#\e(B
 
 \e$B$3$N4X?t$O!"%0%k!<%WL>$,\e(B @code{car} \e$B$G!"$=$N5-;v$N0\F0@h$N5-;vHV9f$,\e(B
 @code{cdr} \e$B$G$"$k\e(B cons \e$B%;%k$rJV$7$^$9!#\e(B
 
+\e$B$=$N%0%k!<%W$O!"%P%C%/%(%s%I$,$=$N%0%k!<%W$X$N5-;v$N<}G<$rMW5a$9$kA0$KB8\e(B
+\e$B:_$7$J$1$l$^$J$j$^$;$s!#\e(B
+
 \e$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#\e(B
 
 @item (nnchoke-request-accept-article GROUP &optional SERVER LAST)
 \e$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#\e(B
 
 @item (nnchoke-request-accept-article GROUP &optional SERVER LAST)
index b31153e..984ec79 100644 (file)
@@ -33,7 +33,7 @@
 \makeindex
 \begin{document}
 
 \makeindex
 \begin{document}
 
-\newcommand{\gnusversionname}{Oort Gnus v0.10}
+\newcommand{\gnusversionname}{Oort Gnus v0.11}
 \newcommand{\gnuschaptername}{}
 \newcommand{\gnussectionname}{}
 
 \newcommand{\gnuschaptername}{}
 \newcommand{\gnussectionname}{}
 
 
 \thispagestyle{empty}
 
 
 \thispagestyle{empty}
 
-Copyright \copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+Copyright \copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003
 Free Software Foundation, Inc.
 
 
 Free Software Foundation, Inc.
 
 
@@ -317,7 +318,7 @@ license to the document, as described in section 6 of the license.
 
 This file documents gnus, the GNU Emacs newsreader.
 
 
 This file documents gnus, the GNU Emacs newsreader.
 
-Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
         Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
         Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
@@ -347,7 +348,8 @@ license to the document, as described in section 6 of the license.
 @page
 
 @vskip 0pt plus 1filll
 @page
 
 @vskip 0pt plus 1filll
-Copyright @copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+Copyright @copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003
         Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
         Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
@@ -1785,6 +1787,9 @@ Number of ticked articles.
 @item R
 Number of read articles.
 
 @item R
 Number of read articles.
 
+@item U
+Number of unseen articles.
+
 @item t
 Estimated total number of articles.  (This is really @var{max-number}
 minus @var{min-number} plus 1.)
 @item t
 Estimated total number of articles.  (This is really @var{max-number}
 minus @var{min-number} plus 1.)
@@ -2885,7 +2890,7 @@ See also @code{gnus-group-ignored-charsets-alist}.
 
 @item posting-style
 @cindex posting-style
 
 @item posting-style
 @cindex posting-style
-You can store additional posting style information for this group only
+You can store additional posting style information for this group
 here (@pxref{Posting Styles}).  The format is that of an entry in the
 @code{gnus-posting-styles} alist, except that there's no regexp matching
 the group name (of course).  Style elements in this group parameter will
 here (@pxref{Posting Styles}).  The format is that of an entry in the
 @code{gnus-posting-styles} alist, except that there's no regexp matching
 the group name (of course).  Style elements in this group parameter will
@@ -2898,6 +2903,7 @@ like this in the group parameters:
 @example
 (posting-style
   (name "Funky Name")
 @example
 (posting-style
   (name "Funky Name")
+  ("X-My-Header" "Funky Value")
   (signature "Funky Signature"))
 @end example
 
   (signature "Funky Signature"))
 @end example
 
@@ -4969,7 +4975,9 @@ the server and display it in the article buffer.
 @item gnus-select-article-hook
 @vindex gnus-select-article-hook
 This hook is called whenever an article is selected.  By default it
 @item gnus-select-article-hook
 @vindex gnus-select-article-hook
 This hook is called whenever an article is selected.  By default it
-exposes any threads hidden under the selected article.
+exposes any threads hidden under the selected article.  If you wish
+that the Agent saves all articles you read, putting
+@code{gnus-agent-fetch-selected-article} on this hook should do it.
 
 @item gnus-mark-article-hook
 @vindex gnus-mark-article-hook
 
 @item gnus-mark-article-hook
 @vindex gnus-mark-article-hook
@@ -5931,6 +5939,13 @@ or
 @subsection Setting Process Marks
 @cindex setting process marks
 
 @subsection Setting Process Marks
 @cindex setting process marks
 
+Process marks are displayed as @code{#} in the summary buffer, and are
+used for marking articles in such a way that other commands will
+process these articles.  For instance, if you process mark four
+articles and then use the @kbd{*} command, Gnus will enter these four
+commands into the cache.  For more information,
+@pxref{Process/Prefix}.
+
 @table @kbd
 
 @item M P p
 @table @kbd
 
 @item M P p
@@ -8286,11 +8301,34 @@ apostrophe or quotation mark, then try this wash.
 
 @item W k
 @kindex W k (Summary)
 
 @item W k
 @kindex W k (Summary)
+@kindex W Y f (Summary)
 @findex gnus-article-outlook-deuglify-article
 @cindex Outlook Express
 @findex gnus-article-outlook-deuglify-article
 @cindex Outlook Express
-Deuglify broken Outlook (Express) articles and redisplay
+Deuglify broken Outlook (Express) articles.
 (@code{gnus-article-outlook-deuglify-article}).
 
 (@code{gnus-article-outlook-deuglify-article}).
 
+@item W Y u
+@kindex W Y u (Summary)
+@findex gnus-outlook-unwrap-lines
+Unwrap lines that appear to be wrapped citation lines.  You can control
+what lines will be unwrapped by frobbing
+@code{gnus-outlook-deuglify-unwrap-min} and
+@code{gnus-outlook-deuglify-unwrap-max}, indicating the miminum and
+maximum length of an unwrapped citation line.
+(@code{gnus-outlook-deuglify-article}).
+
+@item W Y a
+@kindex W Y a (Summary)
+@findex gnus-outlook-repair-attribution
+Repair a broken attribution line
+(@code{gnus-outlook-repair-attribution}).
+
+@item W Y c
+@kindex W Y c (Summary)
+@findex gnus-outlook-rearrange-citation
+Repair broken citations by rearranging the text.
+(@code{gnus-outlook-rearrange-citation}).
+
 @item W w
 @kindex W w (Summary)
 @findex gnus-article-fill-cited-article
 @item W w
 @kindex W w (Summary)
 @findex gnus-article-fill-cited-article
@@ -8355,10 +8393,10 @@ If a prefix is given, a charset will be asked for.
 
 @vindex gnus-article-wash-function
 The default is to use the function specified by
 
 @vindex gnus-article-wash-function
 The default is to use the function specified by
-@code{mm-inline-text-html-renderer} (@pxref{Customization, , , emacs-mime})
-to convert the @sc{html}, but this is controlled by the
-@code{gnus-article-wash-function} variable.  Pre-defined functions you
-can use include:
+@code{mm-text-html-renderer} (@pxref{(emacs-mime)Display
+Customization}) to convert the @sc{html}, but this is controlled by
+the @code{gnus-article-wash-function} variable.  Pre-defined functions
+you can use include:
 
 @table @code
 @item w3
 
 @table @code
 @item w3
@@ -8917,13 +8955,29 @@ To have all Vcards be ignored, you'd say something like this:
       '("text/x-vcard"))
 @end lisp
 
       '("text/x-vcard"))
 @end lisp
 
+@item gnus-article-loose-mime
+@vindex gnus-article-loose-mime
+If non-@code{nil}, Gnus won't required the @samp{MIME-Version} header
+before interpreting the message as a @sc{mime} message.  This helps
+when reading messages from certain broken mail user agents.  The
+default is @code{nil}.
+
+@item gnus-article-emulate-mime
+@vindex gnus-article-emulate-mime
+There are other, non-@sc{mime} encoding methods used.  The most common
+is @samp{uuencode}, but yEncode is also getting to be popular.  If
+This variable is non-@code{nil}, Gnus will look in message bodies to
+see if it finds these encodings, and if so, it'll run them through the
+Gnus @sc{mime} machinery.  The default is @code{t}.
+
 @item gnus-unbuttonized-mime-types
 @vindex gnus-unbuttonized-mime-types
 This is a list of regexps.  @sc{mime} types that match a regexp from
 this list won't have @sc{mime} buttons inserted unless they aren't
 displayed or this variable is overridden by
 @code{gnus-buttonized-mime-types}.  The default value is
 @item gnus-unbuttonized-mime-types
 @vindex gnus-unbuttonized-mime-types
 This is a list of regexps.  @sc{mime} types that match a regexp from
 this list won't have @sc{mime} buttons inserted unless they aren't
 displayed or this variable is overridden by
 @code{gnus-buttonized-mime-types}.  The default value is
-@code{(".*/.*")}.
+@code{(".*/.*")}.  This variable is only used when
+@code{gnus-inhibit-mime-unbuttonizing} is nil.
 
 @item gnus-buttonized-mime-types
 @vindex gnus-buttonized-mime-types
 
 @item gnus-buttonized-mime-types
 @vindex gnus-buttonized-mime-types
@@ -8931,6 +8985,8 @@ This is a list of regexps.  @sc{mime} types that match a regexp from
 this list will have @sc{mime} buttons inserted unless they aren't
 displayed.  This variable overrides
 @code{gnus-unbuttonized-mime-types}.  The default value is @code{nil}.
 this list will have @sc{mime} buttons inserted unless they aren't
 displayed.  This variable overrides
 @code{gnus-unbuttonized-mime-types}.  The default value is @code{nil}.
+This variable is only used when @code{gnus-inhibit-mime-unbuttonizing}
+is nil.
 
 To see e.g. security buttons but no other buttons, you could set this
 variable to @code{("multipart/signed")} and leave
 
 To see e.g. security buttons but no other buttons, you could set this
 variable to @code{("multipart/signed")} and leave
@@ -9000,7 +9056,7 @@ such unenlightened users, you can make live easier by adding
 @end lisp
 
 @noindent
 @end lisp
 
 @noindent
-to your @file{.gnus} file.
+to your @file{.gnus.el} file.
 
 @end table
 
 
 @end table
 
@@ -9646,7 +9702,7 @@ will tell you (@code{gnus-summary-respool-query}).
 @kindex B t (Summary)
 @findex gnus-summary-respool-trace
 Similarly, this command will display all fancy splitting patterns used
 @kindex B t (Summary)
 @findex gnus-summary-respool-trace
 Similarly, this command will display all fancy splitting patterns used
-when repooling, if any (@code{gnus-summary-respool-trace}).
+when respooling, if any (@code{gnus-summary-respool-trace}).
 
 @item B p
 @kindex B p (Summary)
 
 @item B p
 @kindex B p (Summary)
@@ -12524,7 +12580,7 @@ mail back end of your choice into @code{gnus-secondary-select-methods},
 and things will happen automatically.
 
 For instance, if you want to use @code{nnml} (which is a "one file per
 and things will happen automatically.
 
 For instance, if you want to use @code{nnml} (which is a "one file per
-mail" back end), you could put the following in your @file{.gnus} file:
+mail" back end), you could put the following in your @file{.gnus.el} file:
 
 @lisp
 (setq gnus-secondary-select-methods '((nnml "")))
 
 @lisp
 (setq gnus-secondary-select-methods '((nnml "")))
@@ -13606,7 +13662,7 @@ However, if you change group parameters, you'd have to update
 @code{nnmail-split-fancy} manually.  You can do it by running
 @code{gnus-group-split-update}.  If you'd rather have it updated
 automatically, just tell @code{gnus-group-split-setup} to do it for
 @code{nnmail-split-fancy} manually.  You can do it by running
 @code{gnus-group-split-update}.  If you'd rather have it updated
 automatically, just tell @code{gnus-group-split-setup} to do it for
-you.  For example, add to your @file{.gnus}:
+you.  For example, add to your @file{.gnus.el}:
 
 @lisp
 (gnus-group-split-setup AUTO-UPDATE CATCH-ALL)
 
 @lisp
 (gnus-group-split-setup AUTO-UPDATE CATCH-ALL)
@@ -13736,7 +13792,7 @@ By default, if you have auto expiry switched on, Gnus will mark all the
 articles you read as expirable, no matter if they were read or unread
 before.  To avoid having articles marked as read marked as expirable
 automatically, you can put something like the following in your
 articles you read as expirable, no matter if they were read or unread
 before.  To avoid having articles marked as read marked as expirable
 automatically, you can put something like the following in your
-@file{.gnus} file:
+@file{.gnus.el} file:
 
 @vindex gnus-mark-article-hook
 @lisp
 
 @vindex gnus-mark-article-hook
 @lisp
@@ -16954,13 +17010,6 @@ toggles the plugged/unplugged state of the Gnus Agent.
 * Server Agent Commands::       
 @end menu
 
 * Server Agent Commands::       
 @end menu
 
-You can run a complete batch command from the command line with the
-following incantation:
-
-@cindex gnus-agent-batch
-@example
-$ emacs -batch -l ~/.gnus.el -f gnus-agent-batch
-@end example
 
 
 
 
 
 
@@ -17301,9 +17350,12 @@ Having the Gnus Agent fetch articles (and post whatever messages you've
 written) is quite easy once you've gotten things set up properly.  The
 following shell script will do everything that is necessary:
 
 written) is quite easy once you've gotten things set up properly.  The
 following shell script will do everything that is necessary:
 
+You can run a complete batch command from the command line with the
+following incantation:
+
 @example
 #!/bin/sh
 @example
 #!/bin/sh
-emacs -batch -l ~/.emacs -f gnus-agent-batch >/dev/null
+emacs -batch -l ~/.emacs -f -l ~/.gnus.el gnus-agent-batch >/dev/null 2>&1
 @end example
 
 
 @end example
 
 
@@ -17317,7 +17369,9 @@ may ask:
 @table @dfn
 @item If I read an article while plugged, do they get entered into the Agent?
 
 @table @dfn
 @item If I read an article while plugged, do they get entered into the Agent?
 
-@strong{No}.
+@strong{No}.  If you want this behaviour, add
+@code{gnus-agent-fetch-selected-article} to
+@code{gnus-select-article-hook}.
 
 @item If I read an article while plugged, and the article already exists in the Agent, will it get downloaded once more?
 
 
 @item If I read an article while plugged, and the article already exists in the Agent, will it get downloaded once more?
 
@@ -19602,8 +19656,8 @@ You can redefine the function that moves the point to the colon.  The
 function is called @code{gnus-goto-colon}.
 
 But perhaps the most convenient way to deal with this, if you don't want
 function is called @code{gnus-goto-colon}.
 
 But perhaps the most convenient way to deal with this, if you don't want
-to have a colon in your line, is to use the @samp{%C} specifier.  If you
-put a @samp{%C} somewhere in your format line definition, Gnus will
+to have a colon in your line, is to use the @samp{%*} specifier.  If you
+put a @samp{%*} somewhere in your format line definition, Gnus will
 place point there.
 
 
 place point there.
 
 
@@ -20222,7 +20276,7 @@ seconds.  This is 60 by default.  If you change that variable,
 all the timings in the handlers will be affected.)
 
 So, if you want to add a handler, you could put something like this in
 all the timings in the handlers will be affected.)
 
 So, if you want to add a handler, you could put something like this in
-your @file{.gnus} file:
+your @file{.gnus.el} file:
 
 @findex gnus-demon-add-handler
 @lisp
 
 @findex gnus-demon-add-handler
 @lisp
@@ -20239,7 +20293,7 @@ Some ready-made functions to do this have been created:
 @code{gnus-demon-add-nntp-close-connection},
 @code{gnus-demon-add-scan-timestamps}, @code{gnus-demon-add-rescan}, and
 @code{gnus-demon-add-scanmail}.  Just put those functions in your
 @code{gnus-demon-add-nntp-close-connection},
 @code{gnus-demon-add-scan-timestamps}, @code{gnus-demon-add-rescan}, and
 @code{gnus-demon-add-scanmail}.  Just put those functions in your
-@file{.gnus} if you want those abilities.
+@file{.gnus.el} if you want those abilities.
 
 @findex gnus-demon-init
 @findex gnus-demon-cancel
 
 @findex gnus-demon-init
 @findex gnus-demon-cancel
@@ -21353,7 +21407,9 @@ a useful contribution, however.
 
 The idea behind @code{spam.el} is to have a control center for spam detection
 and filtering in Gnus.  To that end, @code{spam.el} does two things: it
 
 The idea behind @code{spam.el} is to have a control center for spam detection
 and filtering in Gnus.  To that end, @code{spam.el} does two things: it
-filters incoming mail, and it analyzes mail known to be spam.
+filters incoming mail, and it analyzes mail known to be spam or ham.
+@emph{Ham} is the name used throughout @code{spam.el} to indicate
+non-spam messages.
 
 So, what happens when you load @code{spam.el}?  First of all, you get
 the following keyboard commands:
 
 So, what happens when you load @code{spam.el}?  First of all, you get
 the following keyboard commands:
@@ -21371,7 +21427,8 @@ the following keyboard commands:
 
 Mark current article as spam, showing it with the @samp{H} mark.
 Whenever you see a spam article, make sure to mark its summary line
 
 Mark current article as spam, showing it with the @samp{H} mark.
 Whenever you see a spam article, make sure to mark its summary line
-with @kbd{M-d} before leaving the group.
+with @kbd{M-d} before leaving the group.  This is done automatically
+for unread articles in @emph{spam} groups.
 
 @item M s t
 @itemx S t
 
 @item M s t
 @itemx S t
@@ -21387,44 +21444,89 @@ properly.
 
 @end table
 
 
 @end table
 
-Gnus can learn from the spam you get.  All you have to do is collect
-your spam in one or more spam groups, and set the variable
-@code{spam-junk-mailgroups} as appropriate.  In these groups, all messages
-are considered to be spam by default: they get the @samp{H} mark.  You must
-review these messages from time to time and remove the @samp{H} mark for
-every message that is not spam after all.  When you leave a spam
-group, all messages that continue with the @samp{H} mark, are passed on to
-the spam-detection engine (bogofilter, ifile, and others).  To remove
-the @samp{H} mark, you can use @kbd{M-u} to "unread" the article, or @kbd{d} for
-declaring it read the non-spam way.  When you leave a group, all @samp{H}
-marked articles, saved or unsaved, are sent to Bogofilter or ifile
-(depending on @code{spam-use-bogofilter} and @code{spam-use-ifile}), which will study
-them as spam samples.
+Also, when you load @code{spam.el}, you will be able to customize its
+variables.  Try @code{customize-group} on the @samp{spam} variable
+group.
+
+The concepts of ham processors and spam processors are very important.
+Ham processors and spam processors for a group can be set with the
+@code{spam-process} group parameter, or the
+@code{gnus-spam-process-newsgroups} variable.  Ham processors take
+mail known to be non-spam (@emph{ham}) and process it in some way so
+that later similar mail will also be considered non-spam.  Spam
+processors take mail known to be spam and process it so similar spam
+will be detected later.
+
+Gnus learns from the spam you get.  You have to collect your spam in
+one or more spam groups, and set or customize the variable
+@code{spam-junk-mailgroups} as appropriate.  You can also declare
+groups to contain spam by setting their group parameter
+@code{spam-contents} to @code{gnus-group-spam-classification-spam}, or
+by customizing the corresponding variable
+@code{gnus-spam-newsgroup-contents}.  The @code{spam-contents} group
+parameter and the @code{gnus-spam-newsgroup-contents} variable can
+also be used to declare groups as @emph{ham} groups if you set their
+classification to @code{gnus-group-spam-classification-ham}.  If
+groups are not classified by means of @code{spam-junk-mailgroups},
+@code{spam-contents}, or @code{gnus-spam-newsgroup-contents}, they are
+considered @emph{unclassified}.  All groups are unclassified by
+default.
+
+In spam groups, all messages are considered to be spam by default:
+they get the @samp{H} mark when you enter the group.  You must review
+these messages from time to time and remove the @samp{H} mark for
+every message that is not spam after all.  To remove the @samp{H}
+mark, you can use @kbd{M-u} to "unread" the article, or @kbd{d} for
+declaring it read the non-spam way.  When you leave a group, all
+spam-marked (@samp{H}) articles are sent to a spam processor which
+will study them as spam samples.
 
 Messages may also be deleted in various other ways, and unless
 
 Messages may also be deleted in various other ways, and unless
-@code{spam-ham-marks-form} gets overridden below, marks @samp{R} and @samp{r} for
-default read or explicit delete, marks @samp{X} and @samp{K} for automatic or
-explicit kills, as well as mark @samp{Y} for low scores, are all considered
-to be associated with articles which are not spam.  This assumption
-might be false, in particular if you use kill files or score files as
-means for detecting genuine spam, you should then adjust
-@code{spam-ham-marks-form}.  When you leave a group, all _unsaved_ articles
-bearing any the above marks are sent to Bogofilter or ifile, which
-will study these as not-spam samples.  If you explicit kill a lot, you
-might sometimes end up with articles marked @samp{K} which you never saw,
-and which might accidentally contain spam.  Best is to make sure that
-real spam is marked with @samp{H}, and nothing else.
-
-All other marks do not contribute to Bogofilter or ifile
-pre-conditioning.  In particular, ticked, dormant or souped articles
-are likely to contribute later, when they will get deleted for real,
-so there is no need to use them prematurely.  Explicitly expired
-articles do not contribute, command @kbd{E} is a way to get rid of an
-article without Bogofilter or ifile ever seeing it.
-
-@strong{TODO: @code{spam-use-ifile} does not process spam articles on group exit.
-I'm waiting for info from the author of @code{ifile-gnus.el}, because I think
-that functionality should go in @code{ifile-gnus.el} rather than @code{spam.el}.}
+@code{spam-ham-marks} gets overridden below, marks @samp{R} and
+@samp{r} for default read or explicit delete, marks @samp{X} and
+@samp{K} for automatic or explicit kills, as well as mark @samp{Y} for
+low scores, are all considered to be associated with articles which
+are not spam.  This assumption might be false, in particular if you
+use kill files or score files as means for detecting genuine spam, you
+should then adjust the @code{spam-ham-marks} variable.
+
+@defvar spam-ham-marks
+You can customize this variable to be the list of marks you want to
+consider ham.  By default, the list contains the deleted, read,
+killed, kill-filed, and low-score marks.
+@end defvar
+
+@defvar spam-spam-marks
+You can customize this variable to be the list of marks you want to
+consider spam.  By default, the list contains only the spam mark.
+@end defvar
+
+When you leave @emph{any} group, regardless of its
+@code{spam-contents} classification, all spam-marked articles are sent
+to a spam processor, which will study these as spam samples.  If you
+explicit kill a lot, you might sometimes end up with articles marked
+@samp{K} which you never saw, and which might accidentally contain
+spam.  Best is to make sure that real spam is marked with @samp{H},
+and nothing else.
+
+When you leave a @emph{spam} group, all spam-marked articles are
+marked as expired after processing with the spam processor.  This is
+not done for @emph{unclassified} or @emph{ham} groups.  Also, any
+@strong{ham} articles in a spam group will be moved to a location
+determined by either the @code{ham-process-destination} group
+parameter or the @code{gnus-ham-process-destinations} variable.  The
+location is a group name.  If the @code{ham-process-destination}
+parameter is not set, spam articles are only expired.
+
+When you leave a @emph{ham} group, all ham-marked articles are sent to
+a ham processor, which will study these as non-spam samples.
+
+When you leave a @emph{ham} or @emph{unclassified} group, all
+@strong{spam} articles are moved to a location determined by either
+the @code{spam-process-destination} group parameter or the
+@code{gnus-spam-process-destinations} variable.  The location is a
+group name.  If the @code{spam-process-destination} parameter is not
+set, the spam articles are only expired.
 
 To use the @code{spam.el} facilities for incoming mail filtering, you
 must add the following to your fancy split list
 
 To use the @code{spam.el} facilities for incoming mail filtering, you
 must add the following to your fancy split list
@@ -21438,19 +21540,29 @@ Note that the fancy split may be called @code{nnmail-split-fancy} or
 @code{nnimap-split-fancy}, depending on whether you use the nnmail or
 nnimap back ends to retrieve your mail.
 
 @code{nnimap-split-fancy}, depending on whether you use the nnmail or
 nnimap back ends to retrieve your mail.
 
-The @code{spam-split} function will process incoming mail and send the mail
-considered to be spam into the group name given by the variable
-@code{spam-split-group}.  Usually that group name is @samp{spam}.
+The @code{spam-split} function will process incoming mail and send the
+mail considered to be spam into the group name given by the variable
+@code{spam-split-group}.  By default that group name is @samp{spam},
+but you can customize it.
+
+@emph{TODO: Currently, spam.el only supports insertion of articles
+into a backend.  There is no way to tell spam.el that an article is no
+longer spam or ham.}
+
+@emph{TODO: spam.el needs to provide a uniform way of training all the
+statistical databases.  Some have that functionality built-in, others
+don't.}
 
 The following are the methods you can use to control the behavior of
 
 The following are the methods you can use to control the behavior of
-@code{spam-split}:
+@code{spam-split} and their corresponding spam and ham processors:
 
 @menu
 * Blacklists and Whitelists::   
 * BBDB Whitelists::             
 * Blackholes::                  
 * Bogofilter::                  
 
 @menu
 * Blacklists and Whitelists::   
 * BBDB Whitelists::             
 * Blackholes::                  
 * Bogofilter::                  
-* Ifile spam filtering::        
+* ifile spam filtering::        
+* spam-stat spam filtering::    
 * Extending spam.el::           
 @end menu
 
 * Extending spam.el::           
 @end menu
 
@@ -21462,30 +21574,57 @@ The following are the methods you can use to control the behavior of
 @cindex spam.el
 
 @defvar spam-use-blacklist
 @cindex spam.el
 
 @defvar spam-use-blacklist
-Set this variables to t (the default) if you want to use blacklists.
+Set this variable to t if you want to use blacklists when splitting
+incoming mail.  Messages whose senders are in the blacklist will be
+sent to the @code{spam-split-group}.  This is an explicit filter,
+meaning that it acts only on mail senders @emph{declared} to be
+spammers.
 @end defvar
 
 @defvar spam-use-whitelist
 @end defvar
 
 @defvar spam-use-whitelist
-Set this variables to t if you want to use whitelists.
+Set this variable to t if you want to use whitelists when splitting
+incoming mail.  Messages whose senders are not in the whitelist will
+be sent to the @code{spam-split-group}.  This is an implicit filter,
+meaning it believes everyone to be a spammer unless told otherwise.
+Use with care.
+@end defvar
+
+@defvar gnus-group-spam-exit-processor-blacklist
+Add this symbol to a group's @code{spam-process} parameter by
+customizing the group parameters or the
+@code{gnus-spam-process-newsgroups} variable.  When this symbol is
+added to a group's @code{spam-process} parameter, the senders of
+spam-marked articles will be added to the blacklist.
+@end defvar
+
+@defvar gnus-group-ham-exit-processor-whitelist
+Add this symbol to a group's @code{spam-process} parameter by
+customizing the group parameters or the
+@code{gnus-spam-process-newsgroups} variable.  When this symbol is
+added to a group's @code{spam-process} parameter, the senders of
+ham-marked articles in @emph{ham} groups will be added to the
+whitelist.  Note that this ham processor has no effect in @emph{spam}
+or @emph{unclassified} groups.
 @end defvar
 
 Blacklists are lists of regular expressions matching addresses you
 consider to be spam senders.  For instance, to block mail from any
 sender at @samp{vmadmin.com}, you can put @samp{vmadmin.com} in your
 @end defvar
 
 Blacklists are lists of regular expressions matching addresses you
 consider to be spam senders.  For instance, to block mail from any
 sender at @samp{vmadmin.com}, you can put @samp{vmadmin.com} in your
-blacklist.  Since you start out with an empty blacklist, no harm is
-done by having the @code{spam-use-blacklist} variable set, so it is
-set by default.  Blacklist entries use the Emacs regular expression
-syntax.
+blacklist.  You start out with an empty blacklist.  Blacklist entries
+use the Emacs regular expression syntax.
 
 Conversely, whitelists tell Gnus what addresses are considered
 legitimate.  All non-whitelisted addresses are considered spammers.
 This option is probably not useful for most Gnus users unless the
 
 Conversely, whitelists tell Gnus what addresses are considered
 legitimate.  All non-whitelisted addresses are considered spammers.
 This option is probably not useful for most Gnus users unless the
-whitelists is very comprehensive.  Also see @ref{BBDB Whitelists}.
-Whitelist entries use the Emacs regular expression syntax.
+whitelists is very comprehensive or permissive.  Also see @ref{BBDB
+Whitelists}.  Whitelist entries use the Emacs regular expression
+syntax.
 
 
-The Blacklist and whitelist location can be customized with the
-@code{spam-directory} variable (@file{~/News/spam} by default).  The whitelist
-and blacklist files will be in that directory, named @file{whitelist} and
+The blacklist and whitelist file locations can be customized with the
+@code{spam-directory} variable (@file{~/News/spam} by default), or
+the @code{spam-whitelist} and @code{spam-blacklist} variables
+directly.  The whitelist and blacklist files will by default be in the
+@code{spam-directory} directory, named @file{whitelist} and
 @file{blacklist} respectively.
 
 @node BBDB Whitelists
 @file{blacklist} respectively.
 
 @node BBDB Whitelists
@@ -21495,16 +21634,26 @@ and blacklist files will be in that directory, named @file{whitelist} and
 @cindex BBDB, spam filtering
 @cindex spam.el
 
 @cindex BBDB, spam filtering
 @cindex spam.el
 
-@defvar spam-use-bbdb
+@defvar spam-use-BBDB
 
 Analogous to @code{spam-use-whitelist} (@pxref{Blacklists and
 Whitelists}), but uses the BBDB as the source of whitelisted addresses,
 without regular expressions.  You must have the BBDB loaded for
 
 Analogous to @code{spam-use-whitelist} (@pxref{Blacklists and
 Whitelists}), but uses the BBDB as the source of whitelisted addresses,
 without regular expressions.  You must have the BBDB loaded for
-@code{spam-use-bbdb} to work properly.  Only addresses in the BBDB
+@code{spam-use-BBDB} to work properly.  Only addresses in the BBDB
 will be allowed through; all others will be classified as spam.
 
 @end defvar
 
 will be allowed through; all others will be classified as spam.
 
 @end defvar
 
+@defvar gnus-group-ham-exit-processor-BBDB
+Add this symbol to a group's @code{spam-process} parameter by
+customizing the group parameters or the
+@code{gnus-spam-process-newsgroups} variable.  When this symbol is
+added to a group's @code{spam-process} parameter, the senders of
+ham-marked articles in @emph{ham} groups will be added to the
+BBDB.  Note that this ham processor has no effect in @emph{spam}
+or @emph{unclassified} groups.
+@end defvar
+
 @node Blackholes
 @subsubsection Blackholes
 @cindex spam filtering
 @node Blackholes
 @subsubsection Blackholes
 @cindex spam filtering
@@ -21529,6 +21678,22 @@ but you can try it and see if it works for you.
 
 @end defvar
 
 
 @end defvar
 
+@defvar spam-blackhole-servers
+
+The list of servers to consult for blackhole checks.
+
+@end defvar
+
+@defvar spam-use-dig
+
+Use the @code{dig.el} package instead of the @code{dns.el} package.
+The default setting of t is recommended.
+
+@end defvar
+
+Blackhole checks are done only on incoming mail.  There is no spam or
+ham processor for blackholes.
+
 @node Bogofilter
 @subsubsection Bogofilter
 @cindex spam filtering
 @node Bogofilter
 @subsubsection Bogofilter
 @cindex spam filtering
@@ -21537,9 +21702,10 @@ but you can try it and see if it works for you.
 
 @defvar spam-use-bogofilter
 
 
 @defvar spam-use-bogofilter
 
-Set this variable if you want to use Eric Raymond's speedy Bogofilter.
-This has been tested with a locally patched copy of version 0.4.  Make
-sure to read the installation comments in @code{spam.el}.
+Set this variable if you want @code{spam-split} to use Eric Raymond's
+speedy Bogofilter.  This has been tested with a locally patched copy
+of version 0.4.  Make sure to read the installation comments in
+@code{spam.el}.
 
 With a minimum of care for associating the @samp{H} mark for spam
 articles only, Bogofilter training all gets fairly automatic.  You
 
 With a minimum of care for associating the @samp{H} mark for spam
 articles only, Bogofilter training all gets fairly automatic.  You
@@ -21551,34 +21717,114 @@ Bogofilter into displaying in another buffer the @emph{spamicity}
 score of the current article (between 0.0 and 1.0), together with the
 article words which most significantly contribute to the score.
 
 score of the current article (between 0.0 and 1.0), together with the
 article words which most significantly contribute to the score.
 
+If the @code{bogofilter} executable is not in your path, Bogofilter
+processing will be turned off.
+
 @end defvar
 
 @end defvar
 
-@node Ifile spam filtering
-@subsubsection Ifile spam filtering
+
+@defvar gnus-group-spam-exit-processor-bogofilter
+Add this symbol to a group's @code{spam-process} parameter by
+customizing the group parameters or the
+@code{gnus-spam-process-newsgroups} variable.  When this symbol is
+added to a group's @code{spam-process} parameter, spam-marked articles
+will be added to the bogofilter spam database, and ham-marked articles
+will be added to the bogofilter ham database.  @strong{Note that the
+Bogofilter spam processor is the only spam processor to also do ham
+processing.}
+@end defvar
+
+@node ifile spam filtering
+@subsubsection ifile spam filtering
 @cindex spam filtering
 @cindex ifile, spam filtering
 @cindex spam.el
 
 @defvar spam-use-ifile
 
 @cindex spam filtering
 @cindex ifile, spam filtering
 @cindex spam.el
 
 @defvar spam-use-ifile
 
-Enable this variable if you want to use Ifile, a statistical analyzer
-similar to Bogofilter.  Currently you must have @code{ifile-gnus.el}
-loaded.  The integration of Ifile with @code{spam.el} is not finished
-yet, but you can use @code{ifile-gnus.el} on its own if you like.
+Enable this variable if you want @code{spam-split} to use ifile, a
+statistical analyzer similar to Bogofilter.
+
+@end defvar
+
+@defvar spam-ifile-all-categories
+
+Enable this variable if you want @code{spam-use-ifile} to give you all
+the ifile categories, not just spam/non-spam.  If you use this, make
+sure you train ifile as described in its documentation.
+
+@end defvar
+
+@defvar spam-ifile-spam-category
+
+This is the category of spam messages as far as ifile is concerned.
+The actual string used is irrelevant, but you probably want to leave
+the default value of @samp{spam}.
+@end defvar
+
+@defvar spam-ifile-database-path
+
+This is the filename for the ifile database.  It is not specified by
+default, so ifile will use its own default database name.
 
 @end defvar
 
 
 @end defvar
 
+The ifile mail classifier is similar to Bogofilter in intent and
+purpose.  A ham and a spam processor are provided, plus the
+@code{spam-use-ifile} variable to indicate to spam-split that ifile
+should be used.  The 1.2.1 version of ifile was used to test this
+functionality.
+
+@node spam-stat spam filtering
+@subsubsection spam-stat spam filtering
+@cindex spam filtering
+@cindex spam-stat, spam filtering
+@cindex spam-stat.el
+@cindex spam.el
+
+@xref{Filtering Spam Using Statistics (spam-stat.el)}.
+
+@defvar spam-use-stat
+
+Enable this variable if you want @code{spam-split} to use
+spam-stat.el, an Emacs Lisp statistical analyzer.
+
+@end defvar
+
+@defvar gnus-group-spam-exit-processor-stat
+Add this symbol to a group's @code{spam-process} parameter by
+customizing the group parameters or the
+@code{gnus-spam-process-newsgroups} variable.  When this symbol is
+added to a group's @code{spam-process} parameter, the spam-marked
+articles will be added to the spam-stat database of spam messages.
+@end defvar
+
+@defvar gnus-group-ham-exit-processor-stat
+Add this symbol to a group's @code{spam-process} parameter by
+customizing the group parameters or the
+@code{gnus-spam-process-newsgroups} variable.  When this symbol is
+added to a group's @code{spam-process} parameter, the ham-marked
+articles in @emph{ham} groups will be added to the spam-stat database
+of non-spam messages.  Note that this ham processor has no effect in
+@emph{spam} or @emph{unclassified} groups.
+@end defvar
+
+This enables spam.el to cooperate with spam-stat.el.  spam-stat.el
+provides an internal (Lisp-only) spam database, which unlike ifile or
+Bogofilter does not require external programs.  A spam and a ham
+processor, and the @code{spam-use-stat} variable for @code{spam-split}
+are provided.
+
 @node Extending spam.el
 @subsubsection Extending spam.el
 @cindex spam filtering
 @cindex spam.el, extending
 @cindex extending spam.el
 
 @node Extending spam.el
 @subsubsection Extending spam.el
 @cindex spam filtering
 @cindex spam.el, extending
 @cindex extending spam.el
 
-Say you want to add a new back end called blackbox.  Provide the following:
+Say you want to add a new back end called blackbox.  For filtering
+incoming mail, provide the following:
 
 @enumerate
 
 @enumerate
-@item
-documentation
 
 @item
 code
 
 @item
 code
@@ -21602,6 +21848,62 @@ Write the @code{spam-check-blackbox} function.  It should return
 @code{spam-check-*} functions for examples of what you can do.
 @end enumerate
 
 @code{spam-check-*} functions for examples of what you can do.
 @end enumerate
 
+For processing spam and ham messages, provide the following:
+
+@enumerate
+
+@item
+code 
+
+Note you don't have to provide a spam or a ham processor.  Only
+provide them if Blackbox supports spam or ham processing.
+
+@example
+(defvar gnus-group-spam-exit-processor-blackbox "blackbox"
+  "The Blackbox summary exit spam processor.
+Only applicable to spam groups.")
+
+(defvar gnus-group-ham-exit-processor-blackbox "blackbox"
+  "The whitelist summary exit ham processor.
+Only applicable to non-spam (unclassified and ham) groups.")
+
+@end example
+
+@item
+functionality
+
+@example
+(defun spam-blackbox-register-spam-routine ()
+  (spam-generic-register-routine
+   ;; the spam function
+   (lambda (article)
+     (let ((from (spam-fetch-field-from-fast article)))
+       (when (stringp from)
+          (blackbox-do-something-with-this-spammer from))))
+   ;; the ham function
+   nil))
+
+(defun spam-blackbox-register-ham-routine ()
+  (spam-generic-register-routine
+   ;; the spam function
+   nil
+   ;; the ham function
+   (lambda (article)
+     (let ((from (spam-fetch-field-from-fast article)))
+       (when (stringp from)
+          (blackbox-do-something-with-this-ham-sender from))))))
+@end example
+
+Write the @code{blackbox-do-something-with-this-ham-sender} and
+@code{blackbox-do-something-with-this-spammer} functions.  You can add
+more complex code than fetching the message sender, but keep in mind
+that retrieving the whole message takes significantly longer than the
+sender through @code{spam-fetch-field-from-fast}, because the message
+senders are kept in memory by Gnus.
+
+@end enumerate
+
+
 @node Filtering Spam Using Statistics (spam-stat.el)
 @subsection Filtering Spam Using Statistics (spam-stat.el)
 @cindex Paul Graham
 @node Filtering Spam Using Statistics (spam-stat.el)
 @subsection Filtering Spam Using Statistics (spam-stat.el)
 @cindex Paul Graham
@@ -21672,19 +21974,25 @@ the the group @samp{nnml:mail.spam}), and you would call
 @file{~/Mail/mail/misc} (this usually corresponds the the group
 @samp{nnml:mail.misc}).
 
 @file{~/Mail/mail/misc} (this usually corresponds the the group
 @samp{nnml:mail.misc}).
 
+When you are using IMAP, you won't have the mails available locally,
+so that will not work.  One solution is to use the Gnus Agent to cache
+the articles.  Then you can use directories such as
+@file{"~/News/agent/nnimap/mail.yourisp.com/personal_spam"} for
+@code{spam-stat-process-spam-directory}.  @xref{Agent as Cache}.
+
 @defvar spam-stat
 This variable holds the hash-table with all the statistics -- the
 dictionary we have been talking about.  For every word in either
 collection, this hash-table stores a vector describing how often the
 word appeared in spam and often it appeared in non-spam mails.
 @defvar spam-stat
 This variable holds the hash-table with all the statistics -- the
 dictionary we have been talking about.  For every word in either
 collection, this hash-table stores a vector describing how often the
 word appeared in spam and often it appeared in non-spam mails.
+@end defvar
 
 If you want to regenerate the statistics from scratch, you need to
 reset the dictionary.
 
 
 If you want to regenerate the statistics from scratch, you need to
 reset the dictionary.
 
-@end defvar
-
 @defun spam-stat-reset
 Reset the @code{spam-stat} hash-table, deleting all the statistics.
 @defun spam-stat-reset
 Reset the @code{spam-stat} hash-table, deleting all the statistics.
+@end defun
 
 When you are done, you must save the dictionary.  The dictionary may
 be rather large.  If you will not update the dictionary incrementally
 
 When you are done, you must save the dictionary.  The dictionary may
 be rather large.  If you will not update the dictionary incrementally
@@ -21692,7 +22000,6 @@ be rather large.  If you will not update the dictionary incrementally
 can reduce the size of the dictionary by deleting all words that did
 not appear often enough or that do not clearly belong to only spam or
 only non-spam mails.
 can reduce the size of the dictionary by deleting all words that did
 not appear often enough or that do not clearly belong to only spam or
 only non-spam mails.
-@end defun
 
 @defun spam-stat-reduce-size
 Reduce the size of the dictionary.  Use this only if you do not want
 
 @defun spam-stat-reduce-size
 Reduce the size of the dictionary.  Use this only if you do not want
@@ -21723,10 +22030,14 @@ This will load the necessary Gnus code, and the dictionary you
 created.
 
 Next, you need to adapt your fancy splitting rules:  You need to
 created.
 
 Next, you need to adapt your fancy splitting rules:  You need to
-determine how to use @code{spam-stat}.  In the simplest case, you only have
-two groups, @samp{mail.misc} and @samp{mail.spam}.  The following expression says
-that mail is either spam or it should go into @samp{mail.misc}.  If it is
-spam, then @code{spam-stat-split-fancy} will return @samp{mail.spam}.
+determine how to use @code{spam-stat}.  The following examples are for
+the nnml back end.  Using the nnimap back end works just as well.  Just
+use @code{nnimap-split-fancy} instead of @code{nnmail-split-fancy}.
+
+In the simplest case, you only have two groups, @samp{mail.misc} and
+@samp{mail.spam}.  The following expression says that mail is either
+spam or it should go into @samp{mail.misc}.  If it is spam, then
+@code{spam-stat-split-fancy} will return @samp{mail.spam}.
 
 @example
 (setq nnmail-split-fancy
 
 @example
 (setq nnmail-split-fancy
@@ -21739,7 +22050,7 @@ The group to use for spam.  Default is @samp{mail.spam}.
 @end defvar
 
 If you also filter mail with specific subjects into other groups, use
 @end defvar
 
 If you also filter mail with specific subjects into other groups, use
-the following expression.  It only the mails not matching the regular
+the following expression.  Only mails not matching the regular
 expression are considered potential spam.
 
 @example
 expression are considered potential spam.
 
 @example
@@ -21784,66 +22095,58 @@ dictionary!
 The main interface to using @code{spam-stat}, are the following functions:
 
 @defun spam-stat-buffer-is-spam
 The main interface to using @code{spam-stat}, are the following functions:
 
 @defun spam-stat-buffer-is-spam
-called in a buffer, that buffer is considered to be a new spam mail;
-use this for new mail that has not been processed before
-
+Called in a buffer, that buffer is considered to be a new spam mail.
+Use this for new mail that has not been processed before.
 @end defun
 
 @defun spam-stat-buffer-is-no-spam
 @end defun
 
 @defun spam-stat-buffer-is-no-spam
-called in a buffer, that buffer is considered to be a new non-spam
-mail; use this for new mail that has not been processed before
-
+Called in a buffer, that buffer is considered to be a new non-spam
+mail.  Use this for new mail that has not been processed before.
 @end defun
 
 @defun spam-stat-buffer-change-to-spam
 @end defun
 
 @defun spam-stat-buffer-change-to-spam
-called in a buffer, that buffer is no longer considered to be normal
-mail but spam; use this to change the status of a mail that has
-already been processed as non-spam
-
+Called in a buffer, that buffer is no longer considered to be normal
+mail but spam.  Use this to change the status of a mail that has
+already been processed as non-spam.
 @end defun
 
 @defun spam-stat-buffer-change-to-non-spam
 @end defun
 
 @defun spam-stat-buffer-change-to-non-spam
-called in a buffer, that buffer is no longer considered to be spam but
-normal mail; use this to change the status of a mail that has already
-been processed as spam
-
+Called in a buffer, that buffer is no longer considered to be spam but
+normal mail.  Use this to change the status of a mail that has already
+been processed as spam.
 @end defun
 
 @defun spam-stat-save
 @end defun
 
 @defun spam-stat-save
-save the hash table to the file; the filename used is stored in the
-variable @code{spam-stat-file}
-
+Save the hash table to the file.  The filename used is stored in the
+variable @code{spam-stat-file}.
 @end defun
 
 @defun spam-stat-load
 @end defun
 
 @defun spam-stat-load
-load the hash table from a file; the filename used is stored in the
-variable @code{spam-stat-file}
-
+Load the hash table from a file.  The filename used is stored in the
+variable @code{spam-stat-file}.
 @end defun
 
 @defun spam-stat-score-word
 @end defun
 
 @defun spam-stat-score-word
-return the spam score for a word
-
+Return the spam score for a word.
 @end defun
 
 @defun spam-stat-score-buffer
 @end defun
 
 @defun spam-stat-score-buffer
-return the spam score for a buffer
-
+Return the spam score for a buffer.
 @end defun
 
 @defun spam-stat-split-fancy
 @end defun
 
 @defun spam-stat-split-fancy
-for fancy mail splitting; add the rule @samp{(: spam-stat-split-fancy)} to
-@code{nnmail-split-fancy}
+Use this function for fancy mail splitting.  Add the rule @samp{(:
+spam-stat-split-fancy)} to @code{nnmail-split-fancy}
+@end defun
 
 
-This requires the following in your @file{~/.gnus} file:
+Make sure you load the dictionary before using it.  This requires the
+following in your @file{~/.gnus} file:
 
 @example
 (require 'spam-stat)
 (spam-stat-load)
 @end example
 
 
 @example
 (require 'spam-stat)
 (spam-stat-load)
 @end example
 
-@end defun
-
 Typical test will involve calls to the following functions:
 
 @example
 Typical test will involve calls to the following functions:
 
 @example
@@ -22036,8 +22339,8 @@ XEmacs is distributed as a collection of packages.  You should install
 whatever packages the Gnus XEmacs package requires.  The current
 requirements are @samp{gnus}, @samp{w3}, @samp{mh-e},
 @samp{mailcrypt}, @samp{rmail}, @samp{eterm}, @samp{mail-lib},
 whatever packages the Gnus XEmacs package requires.  The current
 requirements are @samp{gnus}, @samp{w3}, @samp{mh-e},
 @samp{mailcrypt}, @samp{rmail}, @samp{eterm}, @samp{mail-lib},
-@samp{xemacs-base}, and @samp{fsf-compat}.  The @samp{misc-games}
-package is required for Morse decoding.
+@samp{xemacs-base}, @samp{sh-script} and @samp{fsf-compat}.  The
+@samp{misc-games} package is required for Morse decoding.
 
 
 @node History
 
 
 @node History
@@ -22773,7 +23076,7 @@ manner, so it should be difficult to lose much data on what you have
 read if your machine should go down (@pxref{Auto Save}).
 
 @item
 read if your machine should go down (@pxref{Auto Save}).
 
 @item
-Gnus now has its own startup file (@file{.gnus}) to avoid cluttering up
+Gnus now has its own startup file (@file{.gnus.el}) to avoid cluttering up
 the @file{.emacs} file.
 
 @item
 the @file{.emacs} file.
 
 @item
@@ -24630,6 +24933,9 @@ optimizations.
 The function should return a cons where the @code{car} is the group name and
 the @code{cdr} is the article number that the article was entered as.
 
 The function should return a cons where the @code{car} is the group name and
 the @code{cdr} is the article number that the article was entered as.
 
+The group should exist before the backend is asked to accept the
+article for that group.
+
 There should be no data returned.
 
 
 There should be no data returned.
 
 
index 4ccd3a6..32d11be 100644 (file)
@@ -1,7 +1,7 @@
 %% include file for the Gnus refcard and booklet
 
 \def\progver{5.10}\def\refver{5.10-1} % program and refcard versions
 %% include file for the Gnus refcard and booklet
 
 \def\progver{5.10}\def\refver{5.10-1} % program and refcard versions
-\def\date{Dec 15th, 2002}
+\def\date{Jan, 2003}
 \def\author{Gnus Bugfixing Girls + Boys $<$bugs@gnus.org$>$}
 
 %%
 \def\author{Gnus Bugfixing Girls + Boys $<$bugs@gnus.org$>$}
 
 %%
@@ -37,7 +37,7 @@
     Copyright \copyright\ 1995 Vladimir Alexiev
     $<$vladimir@cs.ualberta.ca$>$.\\*
     Copyright \copyright\ 2000 Felix Natter $<$fnatter@gmx.net$>$.\\*
     Copyright \copyright\ 1995 Vladimir Alexiev
     $<$vladimir@cs.ualberta.ca$>$.\\*
     Copyright \copyright\ 2000 Felix Natter $<$fnatter@gmx.net$>$.\\*
-    Copyright \copyright\ 2001, 2002 \author.\\*
+    Copyright \copyright\ 2001, 2002, 2003 \author.\\*
     Created from the Gnus manual Copyright \copyright\ 1994 Lars Magne
     Ingebrigtsen.\\*
     and the Emacs Help Bindings feature (C-h b).\\*
     Created from the Gnus manual Copyright \copyright\ 1994 Lars Magne
     Ingebrigtsen.\\*
     and the Emacs Help Bindings feature (C-h b).\\*
   \newcommand{\GroupTopicsGeneral}{%
     {\esamepage
       Topics are ``categories'' for groups. Press t in the group-buffer to
   \newcommand{\GroupTopicsGeneral}{%
     {\esamepage
       Topics are ``categories'' for groups. Press t in the group-buffer to
-      toggle gnus-topic-mode (C-c C-i g Group Topics RET).
+      toggle gnus-topic-mode (C-c C-i g Group Topics RET).\\*
       \begin{keys}{C-c C-x}
         T n     & Prompt for topic {\bf name} and create it.\\
         T m     & {\bf Move} the current group to some other topic [p/p].\\
       \begin{keys}{C-c C-x}
         T n     & Prompt for topic {\bf name} and create it.\\
         T m     & {\bf Move} the current group to some other topic [p/p].\\
         C-c C-s C-c & Sort the summary-buffer by length.\\
         C-c C-s C-n & Sort the summary-buffer by article {\bf number}.\\
         C-c C-s C-s & Sort the summary-buffer by {\bf subject}.\\
         C-c C-s C-c & Sort the summary-buffer by length.\\
         C-c C-s C-n & Sort the summary-buffer by article {\bf number}.\\
         C-c C-s C-s & Sort the summary-buffer by {\bf subject}.\\
+        C-c C-s C-r & Sort the summary-buffer {\bf randomly}.\\
         C-c C-s C-o & Sort the summary-buffer using the default method.\\
       \end{keys}
       With a prefix these functions sort in reverse order.
         C-c C-s C-o & Sort the summary-buffer using the default method.\\
       \end{keys}
       With a prefix these functions sort in reverse order.
       /x   & Limit depending on ``extra'' headers.\\
       /u   & (x) Limit to {\bf unread} articles.
       [Prefix: also exclude ticked and dormant articles]\\
       /x   & Limit depending on ``extra'' headers.\\
       /u   & (x) Limit to {\bf unread} articles.
       [Prefix: also exclude ticked and dormant articles]\\
+      /.   & Limit to unseen articles.\\
       /m   & Limit to articles marked with specified {\bf mark}.\\
       /t   & Ask for a number and exclude articles younger than that many days.
       [Prefix: exclude older articles]\\
       /m   & Limit to articles marked with specified {\bf mark}.\\
       /t   & Ask for a number and exclude articles younger than that many days.
       [Prefix: exclude older articles]\\
 \newcommand{\PostReplyetc}{% formerly \Ssubmap
   {\esamepage
     These commands put you in a separate news or mail buffer. See the section
 \newcommand{\PostReplyetc}{% formerly \Ssubmap
   {\esamepage
     These commands put you in a separate news or mail buffer. See the section
-    about composing messages for more information.
+    about composing messages for more information.\\*
                                 %After
                                 %editing the article, send it by pressing C-c C-c.  If you are in a
                                 %foreign group and want to post the article using the foreign server, give
                                 %After
                                 %editing the article, send it by pressing C-c C-c.  If you are in a
                                 %foreign group and want to post the article using the foreign server, give
   }
 
 \newcommand{\MsgCompositionGeneral}{%
   }
 
 \newcommand{\MsgCompositionGeneral}{%
-  Press C-c ? in the composition-buffer to get this information.
+  Press C-c ? in the composition-buffer to get this information.\\*
   {\esamepage
     \begin{keys}{C-c C-m}
                                 % sending
   {\esamepage
     \begin{keys}{C-c C-m}
                                 % sending
   }
 
 \newcommand{\MsgCompositionMovementArticle}{%
   }
 
 \newcommand{\MsgCompositionMovementArticle}{%
-  The following functions create the header-field if necessary.
+  The following functions create the header-field if necessary.\\*
   {\esamepage
     \begin{keys}{C-c C-f C-u}
       C-c TAB & Move to \textbf{signature}.\\
   {\esamepage
     \begin{keys}{C-c C-f C-u}
       C-c TAB & Move to \textbf{signature}.\\
index 4681aa9..ff1229a 100644 (file)
@@ -22,7 +22,8 @@ This file documents Message, the Emacs message composition mode.
 \e$B$3$N%U%!%$%k$O\e(B Emacs \e$B$N%a%C%;!<%8:n@.%b!<%I$G$"$k\e(B Message \e$B$K4X$9$k@bL@J8\e(B
 \e$B=q$G$9!#\e(B
 
 \e$B$3$N%U%!%$%k$O\e(B Emacs \e$B$N%a%C%;!<%8:n@.%b!<%I$G$"$k\e(B Message \e$B$K4X$9$k@bL@J8\e(B
 \e$B=q$G$9!#\e(B
 
-Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.1 or
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.1 or
@@ -69,7 +70,7 @@ license to the document, as described in section 6 of the license.
 @page
 
 @vskip 0pt plus 1filll
 @page
 
 @vskip 0pt plus 1filll
-Copyright @copyright{} 1996, 1997, 1998, 1999, 2000, 2001, 2002
+Copyright @copyright{} 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
      Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
      Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
@@ -262,6 +263,23 @@ Message \e$B$O%U%)%m!<%"%C%W$,$I$3$K9T$/$+$rIaDL$NJ}K!$r;H$C$F7hDj$7$^$9$,!"\e(B
 @code{message-cancel-message} \e$B$NCM$,<h$j>C$75-;v$NK\J8$KA^F~$5$l$^$9!#%G%#\e(B
 \e$B%U%)%k%H$O\e(B @samp{I am canceling my own article.} \e$B$G$9!#\e(B
 
 @code{message-cancel-message} \e$B$NCM$,<h$j>C$75-;v$NK\J8$KA^F~$5$l$^$9!#%G%#\e(B
 \e$B%U%)%k%H$O\e(B @samp{I am canceling my own article.} \e$B$G$9!#\e(B
 
+@cindex Cancel Locks
+@vindex message-insert-canlock
+@cindex canlock
+Message \e$B$,%K%e!<%95-;v$r%]%9%H$9$k$H$-!"%G%#%U%)%k%H\e(B
+\e$B$G\e(B @code{Cancel-Lock} \e$B%X%C%@!<$rA^F~$7$^$9!#$3$l$O0E9f2=$5$l$?%X%C%@!<$G!"\e(B
+\e$B$"$J$?<+?H$,=q$$$?%a!<%C%;!<%8$r$"$J$?$@$1$,<h$j>C$9$3$H$,$G$-$k$3$H$rJ]\e(B
+\e$B>Z$9$k!"$9$0$l$b$N$G$9!#7gE@$O!"\e(B@file{.emacs} \e$B%U%!%$%k\e(B (gnus \e$B$,HkL)\e(B
+\e$B$N\e(B cancel lock \e$B%Q%9%o!<%I\e(B (\e$B:G=i$N$3$N5!G=$r;H$&$H$-$K<+F0E*$K@8@.$5$l\e(B
+\e$B$k\e(B) \e$B$r3JG<$9$k>l=j\e(B) \e$B$r$J$/$7$F$7$^$&$H!"%a%C%;!<%8$r<h$j>C$9$3$H$,$G$-$J\e(B
+\e$B$$$G$"$m$&$3$H$G$9!#\e(B
+
+\e$B$=$N%X%C%@!<$rA^F~$9$k$+$I$&$+$O!"\e(B@code{message-insert-canlock} \e$BJQ?t$K$h$C\e(B
+\e$B$F@)8f$5$l$^$9!#\e(B
+
+\e$B$^$@B?$/$N%K%e!<%9%5!<%P!<$,\e(B @code{Cancel-Lock} \e$B%X%C%@!<$r=EMW;k$7$F$$$^\e(B
+\e$B$;$s$,!">-Mh$OJQ$o$k$3$H$,4|BT$5$l$^$9!#\e(B
+
 @node Superseding
 @section \e$BBeBX\e(B
 
 @node Superseding
 @section \e$BBeBX\e(B
 
@@ -460,7 +478,7 @@ gnus \e$B$K$O$3$NJQ?t$N9%E,$J8uJd$G$"$k$H$3$m$N!"$"$i$+$8$aDj5A$5$l$F$$$k4X\e(B
 \e$B@_Dj$5$l$^$9!#\e(B
 
 @kindex C-c C-f C-a
 \e$B@_Dj$5$l$^$9!#\e(B
 
 @kindex C-c C-f C-a
-@findex message-gen-unsubscribed-mft
+@findex message-generate-unsubscribed-mail-followup-to
 @kindex C-c C-f C-m
 @findex message-goto-mail-followup-to
 \e$B$&!<$`!#$=$&$9$k$H$"$J$?$O!V9XFI$7$F$$$J$$%a!<%j%s%0%j%9%H$K%a!<%k$rAw?.\e(B
 @kindex C-c C-f C-m
 @findex message-goto-mail-followup-to
 \e$B$&!<$`!#$=$&$9$k$H$"$J$?$O!V9XFI$7$F$$$J$$%a!<%j%s%0%j%9%H$K%a!<%k$rAw?.\e(B
@@ -468,9 +486,10 @@ gnus \e$B$K$O$3$NJQ?t$N9%E,$J8uJd$G$"$k$H$3$m$N!"$"$i$+$8$aDj5A$5$l$F$$$k4X\e(B
 \e$B?R$M$^$9$M\e(B (\e$B$?$V$sB>$N?M$O\e(B MFT \e$B$,L5$+$C$?>l9g$HF1MM$K=hM}$7$F$7$^$&$@$m\e(B
 \e$B$&$1$l$I!"C/$+$N\e(B to-address \e$B%0%k!<%W%Q%i%a!<%?$r>e=q$-$9$k$?$a$K!"L@<(E*\e(B
 \e$B$J\e(B MFT \e$B$r;H$&$3$H$,$G$-$k$N$G$9\e(B)\e$B!#4X\e(B
 \e$B?R$M$^$9$M\e(B (\e$B$?$V$sB>$N?M$O\e(B MFT \e$B$,L5$+$C$?>l9g$HF1MM$K=hM}$7$F$7$^$&$@$m\e(B
 \e$B$&$1$l$I!"C/$+$N\e(B to-address \e$B%0%k!<%W%Q%i%a!<%?$r>e=q$-$9$k$?$a$K!"L@<(E*\e(B
 \e$B$J\e(B MFT \e$B$r;H$&$3$H$,$G$-$k$N$G$9\e(B)\e$B!#4X\e(B
-\e$B?t\e(B @code{message-gen-unsubscribed-mft} \e$B$,Lr$KN)$D$3$H$,$"$k$G$7$g$&!#$3\e(B
-\e$B$l$O%G%#%U%)%k%H$G\e(B @kbd{C-c C-f C-a} \e$B$K3d$jEv$F$i$l$F$$$^$9!#$I$s$J>l9g\e(B
-\e$B$G$b!"$"$J$?$O<+J,$,A*$s$@\e(B MFT \e$B$rA^F~$9$k$3$H$,$G$-$^$9\e(B; \e$B$=$l$r;O$a$k$N\e(B
+\e$B?t\e(B @code{message-generate-unsubscribed-mail-followup-to} \e$B$,Lr$KN)$D$3$H\e(B
+\e$B$,$"$k$G$7$g$&!#$3$l$O%G%#%U%)%k%H$G\e(B @kbd{C-c C-f C-a} \e$B$K3d$jEv$F$i$l$F\e(B
+\e$B$$$^$9!#$I$s$J>l9g$G$b!"$"$J$?$O<+J,$,A*$s$@\e(B MFT \e$B$rA^F~$9$k$3$H$,$G$-$^\e(B
+\e$B$9\e(B; \e$B$=$l$r;O$a$k$N\e(B
 \e$B$K\e(B @kbd{C-c C-f C-m} (@code{message-goto-mail-followup-to}) \e$B$,=u$1$F$/$l\e(B
 \e$B$k$G$7$g$&!#\e(B
 
 \e$B$K\e(B @kbd{C-c C-f C-m} (@code{message-goto-mail-followup-to}) \e$B$,=u$1$F$/$l\e(B
 \e$B$k$G$7$g$&!#\e(B
 
@@ -504,7 +523,7 @@ MFT \e$B$rB:=E$9$k$3$H$ONI$$%M%A%1%C%H\e(B (nettiquette) \e$B$G$"$k$H9M$($i$l$F$$$^
 
 @menu
 * Buffer Entry::        \e$B%a%C%;!<%8%P%C%U%!$KF~$C$?8e$NL?Na\e(B
 
 @menu
 * Buffer Entry::        \e$B%a%C%;!<%8%P%C%U%!$KF~$C$?8e$NL?Na\e(B
-* Header Commands::     \e$B%X%C%@!<$K0\F0$9$k$?$a$NL?Na\e(B
+* Header Commands::     \e$B%X%C%@!<$K0\F0$^$?$O%X%C%@!<$rJQ99$9$k$?$a$NL?Na\e(B
 * Movement::            \e$B%a%C%;!<%8%P%C%U%!$rF0$-2s$k\e(B
 * Insertion::           \e$B%a%C%;!<%8%P%C%U%!$KJ*;v$rA^F~$9$k\e(B
 @c * MIME::                @sc{mime} considerations.
 * Movement::            \e$B%a%C%;!<%8%P%C%U%!$rF0$-2s$k\e(B
 * Insertion::           \e$B%a%C%;!<%8%P%C%U%!$KJ*;v$rA^F~$9$k\e(B
 @c * MIME::                @sc{mime} considerations.
@@ -531,8 +550,9 @@ MFT \e$B$rB:=E$9$k$3$H$ONI$$%M%A%1%C%H\e(B (nettiquette) \e$B$G$"$k$H9M$($i$l$F$$$^
 @node Header Commands
 @section \e$B%X%C%@!<L?Na\e(B
 
 @node Header Commands
 @section \e$B%X%C%@!<L?Na\e(B
 
-\e$B$3$l$i$NA4$F$NL?Na$OEv$N%X%C%@!<$K0\F0$7$^$9\e(B (@samp{Importance:} \e$B7O$N%3\e(B
-\e$B%^%s%I$ONc30\e(B)\e$B!#$b$7$=$l$,B8:_$7$J$$$H!"$=$l$OA^F~$5$l$^$9!#\e(B
+@subsection \e$B%X%C%@!<$K0\F0$9$k$?$a$NL?Na\e(B
+
+\e$B0J2<$NL?Na$OEv$N%X%C%@!<$K0\F0$7$^$9!#B8:_$7$J$1$l$PA^F~$5$l$^$9!#\e(B
 
 @table @kbd
 
 
 @table @kbd
 
@@ -610,17 +630,122 @@ MFT \e$B$rB:=E$9$k$3$H$ONI$$%M%A%1%C%H\e(B (nettiquette) \e$B$G$"$k$H9M$($i$l$F$$$^
 \e$B$7%P%C%U%!$K$9$G$K$3$N%X%C%@!<$,$"$k>l9g$O!"\e(BRFC 1376 \e$B$K=`$8$?;0$D$N\e(B
 \e$BCM\e(B @samp{low}\e$B!"\e(B@samp{normal} \e$B$*$h$S\e(B @samp{high} \e$B$r=[4D$5$;$^$9!#\e(B
 
 \e$B$7%P%C%U%!$K$9$G$K$3$N%X%C%@!<$,$"$k>l9g$O!"\e(BRFC 1376 \e$B$K=`$8$?;0$D$N\e(B
 \e$BCM\e(B @samp{low}\e$B!"\e(B@samp{normal} \e$B$*$h$S\e(B @samp{high} \e$B$r=[4D$5$;$^$9!#\e(B
 
+@item C-c C-f C-a
+@kindex C-c C-f C-a
+@findex message-generate-unsubscribed-mail-followup-to
+\e$B9VFI$7$F$$$J$$%a!<%j%s%0%j%9%H$KEj9F$9$k>l9g$K8+9g$C\e(B
+\e$B$?\e(B @samp{Mail-Followup-To:} \e$B%X%C%@!<$rA^F~$7$^$9!#9VFI$7$F$$$J$$%a!<%j%s\e(B
+\e$B%0%j%9%H$KK\5-;v$rEj9F$9$k$H$-$O!"\e(B@samp{Mail-Followup-To:} \e$B$r<j$G=q$+$J\e(B
+\e$B$1$l$P$J$j$^$;$s!#FbMF$O!"$U$D$&$O%a!<%j%s%0%j%9%H$N%"%I%l%9$H$"$J$?<+?H\e(B
+\e$B$N%"%I%l%9$G$9!#$3$N4X?t$O$=$N$h$&$J%X%C%@!<$r<+F0E*$KA^F~$7$^$9!#$3$l$O\e(B
+\e$B8=:_$N%a!<%k$N%P%C%U%!$+$i\e(B @samp{To:} \e$B%X%C%@!<$NFbMF$rH4$-=P$7!"$=$l$K8=\e(B
+\e$B:_$N\e(B @code{user-mail-address} \e$B$rDI2C$7$^$9!#\e(B
+
+\e$BG$0U$N0z?t$G$"$k\e(B @code{include-cc} \e$B$,Hs\e(B-@code{nil} \e$B$@$C$?>l9g$O!"\e(B
+@samp{Cc:} \e$B%X%C%@!<$K$"$k%"%I%l%9$b\e(B @samp{Mail-Followup-To:} \e$B%X%C%@!<$K\e(B
+\e$BCV$+$l$^$9!#\e(B
+@end table
+
+@subsection \e$B%X%C%@!<$rJQ99$9$k$?$a$NL?Na\e(B
+
+@table @kbd
+
+@item C-c C-o
+@kindex C-c C-o
+@findex message-sort-headers
+@vindex message-header-format-alist
+@code{message-header-format-alist} \e$B$K=>$C$F%X%C%@!<$rJB$YBX$($^\e(B
+\e$B$9\e(B (@code{message-sort-headers})\e$B!#\e(B
+
+@item C-c C-t
+@kindex C-c C-t
+@findex message-insert-to
+\e$B%U%)%m!<%"%C%W$7$h$&$H$9$k%a%C%;!<%8$N\e(B @code{Reply-To} \e$B$b$7$/\e(B
+\e$B$O\e(B @code{From} \e$B%X%C%@!<$r4^$`\e(B @code{To} \e$B%X%C%@!<$rA^F~$7$^\e(B
+\e$B$9\e(B (@code{message-insert-to})\e$B!#\e(B
+
+@item C-c C-n
+@kindex C-c C-n
+@findex message-insert-newsgroups
+\e$BJVEz$7$F$$$k5-;v$N\e(B @code{Followup-To} \e$B$b$7$/$O!"\e(B@code{Nesgroups} \e$B%X%C%@!<\e(B
+\e$B$rH?1G$7$?\e(B @code{Newsgroups} \e$B%X%C%@!<$rA^F~$7$^\e(B
+\e$B$9\e(B (@code{message-insert-newsgroups})\e$B!#\e(B
+
+@item C-c C-l
+@kindex C-c C-l
+@findex message-to-list-only
+\e$B%a!<%j%s%0%j%9%H08$F$@$1$K%a%C%;!<%8$rAw$j$^$9!#\e(B
+@code{To:} \e$B$H\e(B @code{Cc:} \e$B%X%C%@!<$+$i!"$=$N%a!<%j%s%0%j%9%H0J30$N%"%I%l\e(B
+\e$B%9$r:o=|$7$^$9!#\e(B
+
+@item C-c M-n
+@kindex C-c M-n
+@findex message-insert-disposition-notification-to
+\e$B3+Iu3NG'MW5a$rA^F~$7$^$9!#\e(B
+(@code{message-insert-disposition-notification-to})\e$B!#$3$l$O!"$b$7<u?.<T\e(B
+\e$B$,\e(B RFC 2298 \e$B$r%5%]!<%H$7$F$$$?$i!"H`=w$K$=$N%a%C%;!<%8$r<u$1<h$C$?$3$H$r\e(B
+\e$BCN$i$;$FM_$7$$$3$H$r0UL#$7$^$9!#\e(B
+
 @item M-x message-insert-importance-high
 @kindex M-x message-insert-importance-high
 @findex message-insert-importance-high
 @item M-x message-insert-importance-high
 @kindex M-x message-insert-importance-high
 @findex message-insert-importance-high
-\e$BCM\e(B @samp{high} \e$B$r;}$D\e(B @samp{Importance:} \e$B%X%C%@!<$rA^F~$7$^$9!#I,MW$J\e(B
+@cindex Importance
+\e$BCM\e(B @samp{high} \e$B$r;}$D\e(B @samp{Importance} \e$B%X%C%@!<$rA^F~$7$^$9!#I,MW$J\e(B
 \e$B$i\e(B (\e$B$9$G$K$"$k\e(B) \e$B%X%C%@!<$r>C5n$7$F$+$i!#\e(B
 
 @item M-x message-insert-importance-low
 @kindex M-x message-insert-importance-low
 @findex message-insert-importance-low
 \e$B$i\e(B (\e$B$9$G$K$"$k\e(B) \e$B%X%C%@!<$r>C5n$7$F$+$i!#\e(B
 
 @item M-x message-insert-importance-low
 @kindex M-x message-insert-importance-low
 @findex message-insert-importance-low
-\e$BCM\e(B @samp{low} \e$B$r;}$D\e(B @samp{Importance:} \e$B%X%C%@!<$rA^F~$7$^$9!#I,MW$J\e(B
+@cindex Importance
+\e$BCM\e(B @samp{low} \e$B$r;}$D\e(B @samp{Importance} \e$B%X%C%@!<$rA^F~$7$^$9!#I,MW$J\e(B
 \e$B$i\e(B (\e$B$9$G$K$"$k\e(B) \e$B%X%C%@!<$r>C5n$7$F$+$i!#\e(B
 \e$B$i\e(B (\e$B$9$G$K$"$k\e(B) \e$B%X%C%@!<$r>C5n$7$F$+$i!#\e(B
+
+@item C-c C-f s
+@kindex C-c C-f s
+@findex message-change-subject
+@cindex Subject
+\e$B8=:_$N\e(B @samp{Subject} \e$B%X%C%@!<$rJQ99$7$^$9!#?7$7$$\e(B @samp{Subject} \e$B$r?R$M\e(B
+\e$B$F\e(B @code{(was: <\e$B8E$$BjL>\e(B>)} \e$B$rDI2C$7$^$9!#8E$$BjL>$OJV?.$9$k$H$-$K:o=|$9\e(B
+\e$B$k$3$H$,$G$-$^$9!#\e(B@code{message-subject-trailing-was-query}
+(@pxref{Message Headers}) \e$B$r8+$F2<$5$$!#\e(B
+
+@item C-c C-f x
+@kindex C-c C-f x
+@findex message-cross-post-followup-to
+@vindex message-cross-post-default
+@cindex X-Post
+@cindex cross-post
+\e$B%/%m%9%]%9%H$9$k$?$a$KDI2C$9\e(B
+\e$B$k\e(B @samp{Newsgroups} \e$B$H\e(B @samp{FollowUp-To} \e$B$r?R$M$^$9!#\e(B
+@code{message-cross-post-followup-to} \e$B$O\e(B @samp{FollowUp-To} \e$B$H\e(B @samp{Newsgroups} \e$B$r!"\e(B
+\e$B%0%k!<%W$r;X$7<($9$h$&$K@Z$jNv$-$^$9!#\e(B
+@code{message-cross-post-default} \e$B$,\e(B @code{nil} \e$B$@$C$?$j@\F,0z\e(B
+\e$B?t\e(B @samp{Follow-Up} \e$BIU$-$G8F$P$l$k$H!"%a%C%;!<%8$O%/%m%9%]%9%H$5$l$^$;\e(B
+\e$B$s!#\e(B
+
+@item C-c C-f t
+@kindex C-c C-f t
+@findex message-reduce-to-to-cc
+@samp{To} \e$B%X%C%@!<$NFbMF$r\e(B @samp{Cc} \e$B$+\e(B @samp{Bcc} \e$B%X%C%@!<$NFbMF$GCV$-\e(B
+\e$B49$($^$9!#\e(B
+
+@item C-c C-f w
+@kindex C-c C-f w
+@findex message-insert-wide-reply
+\e$B9-$$JVEz$r$7$?$h$&$K\e(B @samp{To} \e$B$H\e(B @samp{Cc} \e$B%X%C%@!<$rA^F~$7$^$9!#\e(B
+
+@item C-c C-f a
+@kindex C-c C-f a
+@findex message-add-archive-header
+@vindex message-archive-header
+@vindex message-archive-note
+@cindex X-No-Archive
+@samp{X-No-Archive: Yes} \e$B$r%X%C%@!<$KA^F~$7$F!"K\J8$KCm0U=q$-$rF~$l$^$9!#\e(B
+\e$B%X%C%@!<$HCm0U=q$-\e(B
+\e$B$O\e(B @code{message-archive-header} \e$B$H\e(B @code{message-archive-note} \e$B$G%+%9%?\e(B
+\e$B%^%$%:$9$k$3$H$,$G$-$^$9!#@\F,0z?tIU$-$G8F$P$l$k$H!"A^F~$9$k%F%-%9%H$rMW\e(B
+\e$B5a$7$^$9!#K\J8$KCm0U=q$-$rF~$l$?$/$J$$>l9g$O!"\e(B
+@code{message-archive-note} \e$B$r\e(B @code{nil} \e$B$K$7$F2<$5$$!#\e(B
 @end table
 
 @node Movement
 @end table
 
 @node Movement
@@ -685,13 +810,19 @@ MFT \e$B$rB:=E$9$k$3$H$ONI$$%M%A%1%C%H\e(B (nettiquette) \e$B$G$"$k$H9M$($i$l$F$$$^
 @findex message-insert-headers
 \e$B%a%C%;!<%8$N%X%C%@!<$rA^F~$7$^$9\e(B (@code{message-insert-headers})\e$B!#\e(B
 
 @findex message-insert-headers
 \e$B%a%C%;!<%8$N%X%C%@!<$rA^F~$7$^$9\e(B (@code{message-insert-headers})\e$B!#\e(B
 
-@item C-c M-n
-@kindex C-c M-n
-@findex message-insert-disposition-notification-to
-\e$B3+Iu3NG'MW5a$rA^F~$7$^$9!#\e(B
-(@code{message-insert-disposition-notification-to})\e$B!#$3$l$O!"$b$7<u?.<T\e(B
-\e$B$,\e(B RFC 2298 \e$B$r%5%]!<%H$7$F$$$?$i!"H`=w$K$=$N%a%C%;!<%8$r<u$1<h$C$?$3$H$r\e(B
-\e$BCN$i$;$FM_$7$$$3$H$r0UL#$7$^$9!#\e(B
+@item C-c M-m
+@kindex C-c M-m
+@findex message-mark-inserted-region
+\e$B8=:_$N5-;v$N$$$/$D$+$NNN0h$r!"$=$l$i$r0O$`$?$a$N%?%0$G0u$rIU$1$^$9!#\e(B
+@code{message-mark-insert-begin} \e$B$H\e(B @code{message-mark-insert-end} \e$B$r8+\e(B
+\e$B$F2<$5$$!#\e(B
+
+@item C-c M-f
+@kindex C-c M-f
+@findex message-mark-insert-file
+\e$B8=:_$N5-;v$K!"%?%0$G0O$^$l$?%U%!%$%k$rA^F~$7$^$9!#\e(B
+@code{message-mark-insert-begin} \e$B$H\e(B @code{message-mark-insert-end} \e$B$r8+\e(B
+\e$B$F2<$5$$!#\e(B
 @end table
 
 @c FIXTGNUS We should provide MIME manual.
 @end table
 
 @c FIXTGNUS We should provide MIME manual.
@@ -959,27 +1090,6 @@ documentation of your OpenPGP implementation, so we refer to it.
 
 @samp{*} \e$B$O%]%$%s%H$,CV$+$l$F$$$k>l=j$G$9!#\e(B
 
 
 @samp{*} \e$B$O%]%$%s%H$,CV$+$l$F$$$k>l=j$G$9!#\e(B
 
-@item C-c C-t
-@kindex C-c C-t
-@findex message-insert-to
-\e$B%U%)%m!<%"%C%W$7$h$&$H$9$k%a%C%;!<%8$N\e(B @code{Reply-To} \e$B$b$7$/\e(B
-\e$B$O\e(B @code{From} \e$B%X%C%@!<$r4^$`\e(B @code{To} \e$B%X%C%@!<$rA^F~$7$^\e(B
-\e$B$9\e(B (@code{message-insert-to})\e$B!#\e(B
-
-@item C-c C-n
-@kindex C-c C-n
-@findex message-insert-newsgroups
-\e$BJVEz$7$F$$$k5-;v$N\e(B @code{Followup-To} \e$B$b$7$/$O!"\e(B@code{Nesgroups} \e$B%X%C%@!<\e(B
-\e$B$rH?1G$7$?\e(B @code{Newsgroups} \e$B%X%C%@!<$rA^F~$7$^\e(B
-\e$B$9\e(B (@code{message-insert-newsgroups})\e$B!#\e(B
-
-@item C-c C-o
-@kindex C-c C-o
-@findex message-sort-headers
-@vindex message-header-format-alist
-@code{message-header-format-alist} \e$B$K=>$C$F%X%C%@!<$rJB$YBX$($^\e(B
-\e$B$9\e(B (@code{message-sort-headers})\e$B!#\e(B
-
 @item C-c M-r
 @kindex C-c M-r
 @findex message-rename-buffer
 @item C-c M-r
 @kindex C-c M-r
 @findex message-rename-buffer
@@ -1216,6 +1326,18 @@ Message \e$B$,\e(B gnus \e$B>e$GAv$C$F$$$k>l9g!"%a%C%;!<%8%P%C%U%!$O%I%i%U%H%0%k!<%
      "^\\(\\(\\([Rr][Ee]\\|[Ss][Vv]\\|[Aa][Ww]\\): *\\)+\\)")
 @end lisp
 
      "^\\(\\(\\([Rr][Ee]\\|[Ss][Vv]\\|[Aa][Ww]\\): *\\)+\\)")
 @end lisp
 
+@item message-subject-trailing-was-query
+@vindex message-subject-trailing-was-query
+@vindex message-subject-trailing-was-ask-regexp
+@vindex message-subject-trailing-was-regexp
+\e$BBjL>$N9T$KB3$1$k\e(B @samp{(was: <\e$B8E$$BjL>\e(B>)} \e$B$r$I$&$9$k$+$r@)8f$7$^$9!#\e(B
+@code{nil} \e$B$@$C$?$iBjL>$r$=$N$^$^$K$7$F$*$-$^$9!#\e(B@code{ask} \e$B$H$$$&%7%s%\\e(B
+\e$B%k$@$C$?$i!"$I$&$9$k$+$r%f!<%6$K?R$M$^$9!#BjL>\e(B
+\e$B$,\e(B @code{message-subject-trailing-was-ask-regexp} \e$B$K9gCW$9$k>l9g$@$1$G$9\e(B
+\e$B$,!#\e(B@code{message-subject-trailing-was-query} \e$B$,\e(B @code{t} \e$B$@$C$?$i!">o$K\e(B
+\e$B$V$i2<$,$C$?8E$$BjL>$r$O$.<h$j$^$9!#$=$N>l9g\e(B
+\e$B$O\e(B @code{message-subject-trailing-was-regexp} \e$B$,;H$o$l$^$9!#\e(B
+
 @item message-alternative-emails
 @vindex message-alternative-emails
 \e$BBe$o$j$N%a!<%k%"%I%l%9$K9gCW$9$k@55,I=8=$G$9!#:G=i$K%^%C%A$7$?\e(B (\e$BBh0l5A$G\e(B
 @item message-alternative-emails
 @vindex message-alternative-emails
 \e$BBe$o$j$N%a!<%k%"%I%l%9$K9gCW$9$k@55,I=8=$G$9!#:G=i$K%^%C%A$7$?\e(B (\e$BBh0l5A$G\e(B
@@ -1616,6 +1738,14 @@ Hallvard B Furuseth <h.b.furuseth@@usit.uio.no> writes:
 \e$B$=$7$F!"$=$l$>$l$N4X?t$O0zMQJ8$,=$@5$5$l$k$H!"$=$N<~$j$K%]%$%s%H$H%^!<%/\e(B
 \e$B$r;D$5$J$1$l$P$J$j$^$;$s!#\e(B
 
 \e$B$=$7$F!"$=$l$>$l$N4X?t$O0zMQJ8$,=$@5$5$l$k$H!"$=$N<~$j$K%]%$%s%H$H%^!<%/\e(B
 \e$B$r;D$5$J$1$l$P$J$j$^$;$s!#\e(B
 
+@item message-mark-insert-begin
+@vindex message-mark-insert-begin
+\e$B$$$/$D$+$NA^F~$5$l$?%F%-%9%H$N;O$^$j$K0u$rIU$1$k$?$a$NJ8;zNs$G$9!#\e(B
+
+@item message-mark-insert-end
+@vindex message-mark-insert-end
+\e$B$$$/$D$+$NA^F~$5$l$?%F%-%9%H$N=*$j$K0u$rIU$1$k$?$a$NJ8;zNs$G$9!#\e(B
+
 @item message-signature
 @vindex message-signature
 \e$B%a%C%;!<%8%P%C%U%!$N:G8e$KA^F~$5$l$kJ8;zNs$G$9!#$b$7\e(B @code{t} (\e$B$3$l$,=i\e(B
 @item message-signature
 @vindex message-signature
 \e$B%a%C%;!<%8%P%C%U%!$N:G8e$KA^F~$5$l$kJ8;zNs$G$9!#$b$7\e(B @code{t} (\e$B$3$l$,=i\e(B
index 210cc5a..7e19e4a 100644 (file)
@@ -18,7 +18,8 @@
 
 This file documents Message, the Emacs message composition mode.
 
 
 This file documents Message, the Emacs message composition mode.
 
-Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 
+Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.1 or
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.1 or
@@ -235,6 +236,23 @@ The value of @code{message-cancel-message} is inserted in the body of
 the cancel message.  The default is @samp{I am canceling my own
 article.}.
 
 the cancel message.  The default is @samp{I am canceling my own
 article.}.
 
+@cindex Cancel Locks
+@vindex message-insert-canlock
+@cindex canlock
+When Message posts news messages, it inserts @code{Cancel-Lock}
+headers by default.  This is a cryptographic header that ensures that
+only you can cancel your own messages, which is nice.  The downside
+is that if you lose your @file{.emacs} file (which is where Gnus
+stores the secret cancel lock password (which is generated
+automatically the first time you use this feature)), you won't be
+able to cancel your message.
+
+Whether to insert the header or not is controlled by the
+@code{message-insert-canlock} variable.
+
+Not many news servers respect the @code{Cancel-Lock} header yet, but
+this is expected to change in the future.
+
 
 @node Superseding
 @section Superseding
 
 @node Superseding
 @section Superseding
@@ -438,17 +456,17 @@ address, then no MFT is generated; otherwise, a MFT is added to the
 other headers and set to the value of all addresses in To: and Cc:
 
 @kindex C-c C-f C-a
 other headers and set to the value of all addresses in To: and Cc:
 
 @kindex C-c C-f C-a
-@findex message-gen-unsubscribed-mft
+@findex message-generate-unsubscribed-mail-followup-to
 @kindex C-c C-f C-m
 @findex message-goto-mail-followup-to
 Hm. ``So'', you ask, ``what if I send an email to a list I am not
 @kindex C-c C-f C-m
 @findex message-goto-mail-followup-to
 Hm. ``So'', you ask, ``what if I send an email to a list I am not
-subscribed to?  I want my MFT to say that I want an extra copy.''
-(This is supposed to be interpreted by others the same way as if there
-were no MFT, but you can use an explicit MFT to override someone
-else's to-address group parameter.)  The function
-@code{message-gen-unsubscribed-mft} might come in handy.  It is bound
-to @kbd{C-c C-f C-a} by default.  In any case, you can insert a MFT of
-your own choice; @kbd{C-c C-f C-m}
+subscribed to?  I want my MFT to say that I want an extra copy.''  (This
+is supposed to be interpreted by others the same way as if there were no
+MFT, but you can use an explicit MFT to override someone else's
+to-address group parameter.)  The function
+@code{message-generate-unsubscribed-mail-followup-to} might come in
+handy.  It is bound to @kbd{C-c C-f C-a} by default.  In any case, you
+can insert a MFT of your own choice; @kbd{C-c C-f C-m}
 (@code{message-goto-mail-followup-to}) will help you get started.
 
 @c @node Honoring an MFT post
 (@code{message-goto-mail-followup-to}) will help you get started.
 
 @c @node Honoring an MFT post
@@ -481,7 +499,7 @@ better than you do.
 
 @menu
 * Buffer Entry::        Commands after entering a Message buffer.
 
 @menu
 * Buffer Entry::        Commands after entering a Message buffer.
-* Header Commands::     Commands for moving to headers.
+* Header Commands::     Commands for moving headers or changing headers.
 * Movement::            Moving around in message buffers.
 * Insertion::           Inserting things into message buffers.
 * MIME::                @sc{mime} considerations.
 * Movement::            Moving around in message buffers.
 * Insertion::           Inserting things into message buffers.
 * MIME::                @sc{mime} considerations.
@@ -511,9 +529,10 @@ times, you will get back the un-edited message you're responding to.
 @node Header Commands
 @section Header Commands
 
 @node Header Commands
 @section Header Commands
 
-All these commands move to the header in question (except for the
-@samp{Importance:} related commands).  If it doesn't exist, it will be
-inserted.
+@subsection Commands for moving to headers
+
+These following commands move to the header in question.  If it doesn't
+exist, it will be inserted.
 
 @table @kbd
 
 
 @table @kbd
 
@@ -592,17 +611,123 @@ message to the receiver.  If the header is already present in the
 buffer, it cycles between the three valid values according to RFC
 1376: @samp{low}, @samp{normal} and @samp{high}.
 
 buffer, it cycles between the three valid values according to RFC
 1376: @samp{low}, @samp{normal} and @samp{high}.
 
+@item C-c C-f C-a
+@kindex C-c C-f C-a
+@findex message-generate-unsubscribed-mail-followup-to
+Insert a reasonable @samp{Mail-Followup-To:} header
+(@pxref{Mailing Lists}) in a post to an
+unsubscribed list.  When making original posts to a mailing list you are
+not subscribed to, you have to type in a @samp{Mail-Followup-To:} header
+by hand.  The contents, usually, are the addresses of the list and your
+own address.  This function inserts such a header automatically.  It
+fetches the contents of the @samp{To:} header in the current mail
+buffer, and appends the current @code{user-mail-address}.
+
+If the optional argument @code{include-cc} is non-nil, the addresses in
+the @samp{Cc:} header are also put into the @samp{Mail-Followup-To:}
+header.
+
+@end table
+
+@subsection  Commands to change headers
+
+@table @kbd
+
+@item C-c C-o
+@kindex C-c C-o
+@findex message-sort-headers
+@vindex message-header-format-alist
+Sort headers according to @code{message-header-format-alist}
+(@code{message-sort-headers}).
+
+@item C-c C-t
+@kindex C-c C-t
+@findex message-insert-to
+Insert a @code{To} header that contains the @code{Reply-To} or
+@code{From} header of the message you're following up
+(@code{message-insert-to}).
+
+@item C-c C-n
+@kindex C-c C-n
+@findex message-insert-newsgroups
+Insert a @code{Newsgroups} header that reflects the @code{Followup-To}
+or @code{Newsgroups} header of the article you're replying to
+(@code{message-insert-newsgroups}).
+
+@item C-c C-l
+@kindex C-c C-l
+@findex message-to-list-only
+Send a message to the list only.  Remove all addresses but the list
+address from @code{To:} and @code{Cc:} headers.
+
+@item C-c M-n
+@kindex C-c M-n
+@findex message-insert-disposition-notification-to
+Insert a request for a disposition
+notification. (@code{message-insert-disposition-notification-to}).
+This means that if the recipient support RFC 2298 she might send you a
+notification that she received the message.
+
 @item M-x message-insert-importance-high
 @kindex M-x message-insert-importance-high
 @findex message-insert-importance-high
 @item M-x message-insert-importance-high
 @kindex M-x message-insert-importance-high
 @findex message-insert-importance-high
-Insert a @samp{Importance:} header with a value of @samp{high},
+@cindex Importance
+Insert an @samp{Importance} header with a value of @samp{high},
 deleting headers if necessary.
 
 @item M-x message-insert-importance-low
 @kindex M-x message-insert-importance-low
 @findex message-insert-importance-low
 deleting headers if necessary.
 
 @item M-x message-insert-importance-low
 @kindex M-x message-insert-importance-low
 @findex message-insert-importance-low
-Insert a @samp{Importance:} header with a value of @samp{low},
-deleting headers if necessary.
+@cindex Importance
+Insert an @samp{Importance} header with a value of @samp{low}, deleting
+headers if necessary.
+
+@item C-c C-f s
+@kindex C-c C-f s
+@findex message-change-subject
+@cindex Subject
+Change the current @samp{Subject} header.  Ask for new @samp{Subject}
+header and append @code{(was: <Old Subject>)}.  The old subject can be
+stripped on replying, see @code{message-subject-trailing-was-query}
+(@pxref{Message Headers}).
+
+@item C-c C-f x
+@kindex C-c C-f x
+@findex message-cross-post-followup-to
+@vindex message-cross-post-default
+@cindex X-Post
+@cindex cross-post
+Ask for an additional @samp{Newsgroups} and @samp{FollowUp-To} for a
+cross-post.  @code{message-cross-post-followup-to} mangles
+@samp{FollowUp-To} and @samp{Newsgroups} header to point to group.
+If @code{message-cross-post-default} is @code{nil} or if called with a
+prefix-argument @samp{Follow-Up} is set, but the message is not
+cross-posted.
+
+@item C-c C-f t
+@kindex C-c C-f t
+@findex message-reduce-to-to-cc
+Replace contents of @samp{To} header with contents of @samp{Cc} or
+@samp{Bcc} header.
+
+@item C-c C-f w
+@kindex C-c C-f w
+@findex message-insert-wide-reply
+Insert @samp{To} and @samp{Cc} headers as if you were doing a wide
+reply. 
+
+@item C-c C-f a
+@kindex C-c C-f a
+@findex message-add-archive-header
+@vindex message-archive-header
+@vindex message-archive-note
+@cindex X-No-Archive
+Insert @samp{X-No-Archive: Yes} in the header and a note in the body.
+The header and the note can be customized using
+@code{message-archive-header} and @code{message-archive-note}.  When
+called with a prefix argument, ask for a text to insert.  If you don't
+want the note in the body, set @code{message-archive-note} to
+@code{nil}.
 
 @end table
 
 
 @end table
 
@@ -672,13 +797,17 @@ Insert a signature at the end of the buffer
 @findex message-insert-headers
 Insert the message headers (@code{message-insert-headers}).
 
 @findex message-insert-headers
 Insert the message headers (@code{message-insert-headers}).
 
-@item C-c M-n
-@kindex C-c M-n
-@findex message-insert-disposition-notification-to
-Insert a request for a disposition
-notification. (@code{message-insert-disposition-notification-to}).
-This means that if the recipient support RFC 2298 she might send you a
-notification that she received the message.
+@item C-c M-m
+@kindex C-c M-m
+@findex message-mark-inserted-region
+Mark some region in the current article with enclosing tags.
+See @code{message-mark-insert-begin} and @code{message-mark-insert-end}.
+
+@item C-c M-f
+@kindex C-c M-f
+@findex message-mark-insert-file
+Insert a file in the current article with enclosing tags.
+See @code{message-mark-insert-begin} and @code{message-mark-insert-end}.
 
 @end table
 
 
 @end table
 
@@ -946,27 +1075,6 @@ If point is before @samp{And} and you press @kbd{M-RET}, you'll get:
 
 @samp{*} says where point will be placed.
 
 
 @samp{*} says where point will be placed.
 
-@item C-c C-t
-@kindex C-c C-t
-@findex message-insert-to
-Insert a @code{To} header that contains the @code{Reply-To} or
-@code{From} header of the message you're following up
-(@code{message-insert-to}).
-
-@item C-c C-n
-@kindex C-c C-n
-@findex message-insert-newsgroups
-Insert a @code{Newsgroups} header that reflects the @code{Followup-To}
-or @code{Newsgroups} header of the article you're replying to
-(@code{message-insert-newsgroups}).
-
-@item C-c C-o
-@kindex C-c C-o
-@findex message-sort-headers
-@vindex message-header-format-alist
-Sort headers according to @code{message-header-format-alist}
-(@code{message-sort-headers}).
-
 @item C-c M-r
 @kindex C-c M-r
 @findex message-rename-buffer
 @item C-c M-r
 @kindex C-c M-r
 @findex message-rename-buffer
@@ -1215,6 +1323,18 @@ responding to a message:
      "^\\(\\(\\([Rr][Ee]\\|[Ss][Vv]\\|[Aa][Ww]\\): *\\)+\\)")
 @end lisp
 
      "^\\(\\(\\([Rr][Ee]\\|[Ss][Vv]\\|[Aa][Ww]\\): *\\)+\\)")
 @end lisp
 
+@item message-subject-trailing-was-query
+@vindex message-subject-trailing-was-query
+@vindex message-subject-trailing-was-ask-regexp
+@vindex message-subject-trailing-was-regexp
+Controls what to do with trailing @samp{(was: <old subject>)} in subject
+lines.  If @code{nil}, leave the subject unchanged.  If it is the symbol
+@code{ask}, query the user what do do.  In this case, the subject is
+matched against @code{message-subject-trailing-was-ask-regexp}.  If
+@code{message-subject-trailing-was-query} is t, always strip the
+trailing old subject.  In this case,
+@code{message-subject-trailing-was-regexp} is used.
+
 @item message-alternative-emails
 @vindex message-alternative-emails
 A regexp to match the alternative email addresses.  The first matched
 @item message-alternative-emails
 @vindex message-alternative-emails
 A regexp to match the alternative email addresses.  The first matched
@@ -1633,6 +1753,14 @@ This can also be a list of functions.  Each function can find the
 citation between @code{(point)} and @code{(mark t)}.  And each function
 should leave point and mark around the citation text as modified.
 
 citation between @code{(point)} and @code{(mark t)}.  And each function
 should leave point and mark around the citation text as modified.
 
+@item message-mark-insert-begin
+@vindex message-mark-insert-begin
+String to mark the beginning of some inserted text.
+
+@item message-mark-insert-end
+@vindex message-mark-insert-end
+String to mark the end of some inserted text.
+
 @item message-signature
 @vindex message-signature
 String to be inserted at the end of the message buffer.  If @code{t}
 @item message-signature
 @vindex message-signature
 String to be inserted at the end of the message buffer.  If @code{t}
index cf72fb3..92ed19d 100644 (file)
 %
     \subsection*{Summary-Unplugged}
     \SummaryUnplugged
 %
     \subsection*{Summary-Unplugged}
     \SummaryUnplugged
-\pagebreak    
     \subsection*{Mail-Group Commands}
     \MailGroups
     \subsection*{Draft-Group Commands}
     \subsection*{Mail-Group Commands}
     \MailGroups
     \subsection*{Draft-Group Commands}