*** pub/rgnus/lisp/article.el Fri Aug 30 02:13:17 1996 --- rgnus/lisp/article.el Fri Aug 30 22:52:28 1996 *************** *** 458,463 **** --- 458,467 ---- (search-forward "\n\n" nil 'move) (article-mime-decode-quoted-printable (point) (point-max)))))) + (defun article-mime-decode-quoted-printable-buffer () + "Decode Quoted-Printable in the current buffer." + (article-mime-decode-quoted-printable (point-min) (point-max))) + (defun article-mime-decode-quoted-printable (from to) "Decode Quoted-Printable in the region between FROM and TO." (interactive "r") *** pub/rgnus/lisp/gnus-demon.el Fri Aug 30 01:20:49 1996 --- rgnus/lisp/gnus-demon.el Fri Aug 30 22:52:28 1996 *************** *** 29,34 **** --- 29,35 ---- (require 'gnus-int) (require 'nnheader) (require 'gnus) + (require 'timer) (defvar gnus-demon-handlers nil "Alist of daemonic handlers to be run at intervals. *** pub/rgnus/lisp/gnus-group.el Fri Aug 30 00:26:50 1996 --- rgnus/lisp/gnus-group.el Sat Aug 31 03:14:57 1996 *************** *** 308,314 **** "V" gnus-version "s" gnus-group-save-newsrc "z" gnus-group-suspend - ; "Z" gnus-group-clear-dribble "q" gnus-group-exit "Q" gnus-group-quit "?" gnus-group-describe-briefly --- 308,313 ---- *** pub/rgnus/lisp/gnus-int.el Sat Aug 24 23:26:07 1996 --- rgnus/lisp/gnus-int.el Fri Aug 30 22:52:29 1996 *************** *** 390,401 **** (defun gnus-close-backends () ;; Send a close request to all backends that support such a request. (let ((methods gnus-valid-select-methods) ! func) ! (while methods ! (if (fboundp (setq func (intern (concat (caar methods) ! "-request-close")))) ! (funcall func)) ! (setq methods (cdr methods))))) (defun gnus-asynchronous-p (method) (let ((func (gnus-get-function method 'asynchronous-p t))) --- 390,400 ---- (defun gnus-close-backends () ;; Send a close request to all backends that support such a request. (let ((methods gnus-valid-select-methods) ! func method) ! (while (setq method (pop methods)) ! (when (fboundp (setq func (intern ! (concat (car method) "-request-close")))) ! (funcall func))))) (defun gnus-asynchronous-p (method) (let ((func (gnus-get-function method 'asynchronous-p t))) *** pub/rgnus/lisp/gnus-load.el Wed Aug 28 04:05:28 1996 --- rgnus/lisp/gnus-load.el Fri Aug 30 22:52:29 1996 *************** *** 696,701 **** --- 696,702 ---- gnus-dup-unsuppress-article) ("gnus-async" gnus-async-request-fetched-article gnus-async-prefetch-next gnus-async-prefetch-article gnus-async-prefetch-remove-group) + ("article" article-decode-rfc1522) ("gnus-vm" :interactive t gnus-summary-save-in-vm gnus-summary-save-article-vm)))) *** pub/rgnus/lisp/gnus-start.el Fri Aug 30 00:31:56 1996 --- rgnus/lisp/gnus-start.el Sat Aug 31 03:14:58 1996 *************** *** 1421,1427 **** (setq gnus-killed-list (cons group gnus-killed-list)) (gnus-sethash group group gnus-killed-hashtb)))))) ! gnus-active-hashtb)) ;; Get the active file(s) from the backend(s). (defun gnus-read-active-file () --- 1421,1428 ---- (setq gnus-killed-list (cons group gnus-killed-list)) (gnus-sethash group group gnus-killed-hashtb)))))) ! gnus-active-hashtb) ! (gnus-dribble-enter "")) ;; Get the active file(s) from the backend(s). (defun gnus-read-active-file () *************** *** 2332,2338 **** (setq default-directory (if (and gnus-default-directory (file-exists-p gnus-default-directory)) ! (expand-file-name gnus-default-directory) default-directory))) (provide 'gnus-start) --- 2333,2339 ---- (setq default-directory (if (and gnus-default-directory (file-exists-p gnus-default-directory)) ! (file-name-as-directory (expand-file-name gnus-default-directory)) default-directory))) (provide 'gnus-start) *** pub/rgnus/lisp/gnus-sum.el Fri Aug 30 02:53:56 1996 --- rgnus/lisp/gnus-sum.el Sat Aug 31 03:15:00 1996 *************** *** 3671,3676 **** --- 3671,3678 ---- headers id id-dep ref-dep end ref) (save-excursion (set-buffer nntp-server-buffer) + ;; Translate all TAB characters into SPACE characters. + (subst-char-in-region (point-min) (point-max) ?\t ? t) (run-hooks 'gnus-parse-headers-hook) (let ((case-fold-search t) in-reply-to header p lines) *** pub/rgnus/lisp/gnus-topic.el Wed Aug 28 03:20:12 1996 --- rgnus/lisp/gnus-topic.el Sat Aug 31 03:49:59 1996 *************** *** 721,727 **** (if (gnus-group-goto-group group) t ;; The group is no longer visible. ! (let* ((list (assoc (gnus-current-topic) gnus-topic-alist)) (after (cdr (member group (cdr list))))) ;; First try to put point on a group after the current one. (while (and after --- 721,727 ---- (if (gnus-group-goto-group group) t ;; The group is no longer visible. ! (let* ((list (assoc (gnus-group-topic group) gnus-topic-alist)) (after (cdr (member group (cdr list))))) ;; First try to put point on a group after the current one. (while (and after *************** *** 975,993 **** (completing-read "Move to topic: " gnus-topic-alist nil t))) (let ((groups (gnus-group-process-prefix n)) (topicl (assoc topic gnus-topic-alist)) entry) ! (mapcar (lambda (g) ! (gnus-group-remove-mark g) ! (when (and ! (setq entry (assoc (gnus-current-topic) ! gnus-topic-alist)) ! (not copyp)) ! (setcdr entry (gnus-delete-first g (cdr entry)))) ! (nconc topicl (list g))) ! groups) ! (gnus-group-position-point)) ! (gnus-topic-enter-dribble) ! (gnus-group-list-groups)) (defun gnus-topic-remove-group () "Remove the current group from the topic." --- 975,997 ---- (completing-read "Move to topic: " gnus-topic-alist nil t))) (let ((groups (gnus-group-process-prefix n)) (topicl (assoc topic gnus-topic-alist)) + (start-group (progn (forward-line 1) (gnus-group-group-name))) + (start-topic (gnus-group-topic-name)) entry) ! (mapcar ! (lambda (g) ! (gnus-group-remove-mark g) ! (when (and ! (setq entry (assoc (gnus-current-topic) gnus-topic-alist)) ! (not copyp)) ! (setcdr entry (gnus-delete-first g (cdr entry)))) ! (nconc topicl (list g))) ! groups) ! (gnus-topic-enter-dribble) ! (if start-group ! (gnus-group-goto-group start-group) ! (gnus-topic-goto-topic start-topic)) ! (gnus-group-list-groups))) (defun gnus-topic-remove-group () "Remove the current group from the topic." *** pub/rgnus/lisp/gnus-uu.el Sat Aug 17 10:45:41 1996 --- rgnus/lisp/gnus-uu.el Sat Aug 31 03:36:24 1996 *************** *** 1392,1398 **** (call-process-region start-char (point-max) shell-file-name nil (get-buffer-create gnus-uu-output-buffer-name) nil ! shell-command-switch (concat "cd " gnus-uu-work-dir " ; sh")))) state)) ;; Returns the name of what the shar file is going to unpack. --- 1392,1400 ---- (call-process-region start-char (point-max) shell-file-name nil (get-buffer-create gnus-uu-output-buffer-name) nil ! shell-command-switch ! (concat "cd " gnus-uu-work-dir " " ! gnus-shell-command-separator " sh")))) state)) ;; Returns the name of what the shar file is going to unpack. *** pub/rgnus/lisp/gnus.el Fri Aug 30 00:26:55 1996 --- rgnus/lisp/gnus.el Fri Aug 30 22:52:30 1996 *************** *** 28,34 **** (eval '(run-hooks 'gnus-load-hook)) ! (defconst gnus-version-number "0.20" "Version number for this version of Gnus.") (defconst gnus-version (format "Red Gnus v%s" gnus-version-number) --- 28,34 ---- (eval '(run-hooks 'gnus-load-hook)) ! (defconst gnus-version-number "0.21" "Version number for this version of Gnus.") (defconst gnus-version (format "Red Gnus v%s" gnus-version-number) *** pub/rgnus/lisp/message.el Fri Aug 30 01:39:43 1996 --- rgnus/lisp/message.el Fri Aug 30 22:52:31 1996 *************** *** 2594,2601 **** (when ccalist (let ((ccs (cons 'Cc (mapconcat (lambda (addr) (cdr addr)) ccalist ", ")))) ! (when (string-match "^ +" ccs) ! (setq ccs (substring ccs (match-end 0)))) (push ccs follow-to)))))) (widen)) --- 2594,2601 ---- (when ccalist (let ((ccs (cons 'Cc (mapconcat (lambda (addr) (cdr addr)) ccalist ", ")))) ! (when (string-match "^ +" (cdr ccs)) ! (setcdr ccs (substring (cdr ccs) (match-end 0)))) (push ccs follow-to)))))) (widen)) *** pub/rgnus/lisp/nnheader.el Wed Aug 28 01:56:15 1996 --- rgnus/lisp/nnheader.el Fri Aug 30 22:52:31 1996 *************** *** 52,58 **** (eval-and-compile (autoload 'nnmail-message-id "nnmail") (autoload 'mail-position-on-field "sendmail") ! (autoload 'message-remove-header "message")) ;;; Header access macros. --- 52,59 ---- (eval-and-compile (autoload 'nnmail-message-id "nnmail") (autoload 'mail-position-on-field "sendmail") ! (autoload 'message-remove-header "message") ! (autoload 'cancel-function-timers "timers")) ;;; Header access macros. *** pub/rgnus/lisp/nnmail.el Fri Aug 30 01:39:44 1996 --- rgnus/lisp/nnmail.el Sat Aug 31 03:15:02 1996 *************** *** 138,144 **** (defvar nnmail-movemail-program "movemail" "*A command to be executed to move mail from the inbox. ! The default is \"movemail\".") (defvar nnmail-pop-password-required nil "*Non-nil if a password is required when reading mail using POP.") --- 138,148 ---- (defvar nnmail-movemail-program "movemail" "*A command to be executed to move mail from the inbox. ! The default is \"movemail\". ! ! This can also be a function. In that case, the function will be ! called with two parameters -- the name of the INBOX file, and the file ! to be moved to.") (defvar nnmail-pop-password-required nil "*Non-nil if a password is required when reading mail using POP.") *************** *** 178,183 **** --- 182,199 ---- "*Hook called before treating incoming mail. The hook is run in a buffer with all the new, incoming mail.") + (defvar nnmail-prepare-incoming-header-hook nil + "*Hook called narrowed to the headers of each message. + This can be used to remove excessive spaces (and stuff like + that) from the headers before splitting and saving the messages.") + + (defvar nnmail-prepare-incoming-message-hook nil + "*Hook called narrowed to each message.") + + (defvar nnmail-list-identifiers nil + "Regexp that match list identifiers to be removed. + This can also be a list of regexps.") + (defvar nnmail-pre-get-new-mail-hook nil "Hook called just before starting to handle new incoming mail.") *************** *** 429,442 **** (setq errors (generate-new-buffer " *nnmail loss*")) (buffer-disable-undo errors) (let ((default-directory "/")) ! (apply ! 'call-process ! (append ! (list ! (expand-file-name nnmail-movemail-program exec-directory) ! nil errors nil inbox tofile) ! (when nnmail-internal-password ! (list nnmail-internal-password))))) (if (not (buffer-modified-p errors)) ;; No output => movemail won (progn --- 445,460 ---- (setq errors (generate-new-buffer " *nnmail loss*")) (buffer-disable-undo errors) (let ((default-directory "/")) ! (if (nnheader-functionp nnmail-movemail-program) ! (funcall nnmail-movemail-program inbox tofile) ! (apply ! 'call-process ! (append ! (list ! (expand-file-name nnmail-movemail-program exec-directory) ! nil errors nil inbox tofile) ! (when nnmail-internal-password ! (list nnmail-internal-password)))))) (if (not (buffer-modified-p errors)) ;; No output => movemail won (progn *************** *** 538,548 **** " \n0, *unseen,+\n\\(\\*\\*\\* EOOH \\*\\*\\*\n\\)?" nil t) (goto-char (match-end 0)) (delete-region (match-beginning 0) (match-end 0)) ! (setq start (point)) ! ;; Skip all the headers in case there are more "From "s... ! (or (search-forward "\n\n" nil t) ! (search-forward-regexp "^[^:]*\\( .*\\|\\)$" nil t) ! (search-forward " ")) ;; Find the Message-ID header. (save-excursion (if (re-search-backward "^Message-ID:[ \t]*\\(<[^>]*>\\)" nil t) --- 556,571 ---- " \n0, *unseen,+\n\\(\\*\\*\\* EOOH \\*\\*\\*\n\\)?" nil t) (goto-char (match-end 0)) (delete-region (match-beginning 0) (match-end 0)) ! (narrow-to-region ! (setq start (point)) ! (progn ! ;; Skip all the headers in case there are more "From "s... ! (or (search-forward "\n\n" nil t) ! (search-forward-regexp "^[^:]*\\( .*\\|\\)$" nil t) ! (search-forward " ")) ! (point))) ! (run-hooks 'nnmail-prepare-incoming-header-hook) ! (widen) ;; Find the Message-ID header. (save-excursion (if (re-search-backward "^Message-ID:[ \t]*\\(<[^>]*>\\)" nil t) *************** *** 580,589 **** (setq do-search t))) ;; Go to the beginning of the next article - or to the end ;; of the buffer. ! (if do-search ! (if (re-search-forward "^" nil t) ! (goto-char (match-beginning 0)) ! (goto-char (1- (point-max))))) (delete-char 1) ; delete ^_ (save-excursion (save-restriction --- 603,612 ---- (setq do-search t))) ;; Go to the beginning of the next article - or to the end ;; of the buffer. ! (when do-search ! (if (re-search-forward "^" nil t) ! (goto-char (match-beginning 0)) ! (goto-char (1- (point-max))))) (delete-char 1) ; delete ^_ (save-excursion (save-restriction *************** *** 654,659 **** --- 677,683 ---- ;; having a (possibly) faulty header. (beginning-of-line) (insert "X-")) + (run-hooks 'nnmail-prepare-incoming-header-hook) ;; Find the end of this article. (goto-char (point-max)) (widen) *************** *** 727,732 **** --- 751,757 ---- (insert "Original-"))) (forward-line 1) (insert "Message-ID: " (setq message-id (nnmail-message-id)) "\n")) + (run-hooks 'nnmail-prepare-incoming-header-hook) ;; Find the end of this article. (goto-char (point-max)) (widen) *************** *** 881,886 **** --- 906,936 ---- (setq group-alist (cdr group-alist))) (insert "\n")))) + ;;; Message washing functions + + (defun nnmail-remove-leading-whitespace () + "Remove excessive whitespace from all headers." + (goto-char (point-min)) + (while (re-search-forward "^\\([^ :]+: \\) +" nil t) + (replace-match "\\1" t t))) + + (defun nnmail-remove-list-identifiers () + "Remove list identifiers from Subject headers." + (let ((regexp (if (stringp nnmail-list-identifiers) nnmail-list-identifiers + (mapconcat 'identity nnmail-list-identifiers "\\|")))) + (when regexp + (goto-char (point-min)) + (when (re-search-forward + (concat "Subject: +\\(Re: +\\)?\\(" regexp "\\) *") + nil t) + (delete-region (match-beginning 2) (match-end 0)))))) + + (defun nnmail-remove-tabs () + "Translate TAB characters into SPACE characters." + (subst-char-in-region (point-min) (point-max) ?\t ? t)) + + ;;; Utility functions + ;; Written by byer@mv.us.adobe.com (Scott Byer). (defun nnmail-make-complex-temp-name (prefix) (let ((newname (make-temp-name prefix)) *************** *** 1088,1093 **** --- 1138,1144 ---- (search-backward id nil t)))) (defun nnmail-check-duplication (message-id func artnum-func) + (run-hooks 'nnmail-prepare-incoming-message-hook) ;; If this is a duplicate message, then we do not save it. (let* ((duplication (nnmail-cache-id-exists-p message-id)) (action (when duplication *** pub/rgnus/lisp/nntp.el Thu Aug 29 04:19:27 1996 --- rgnus/lisp/nntp.el Fri Aug 30 22:52:33 1996 *************** *** 150,155 **** --- 150,157 ---- (defvar nntp-process-start-point nil) (defvar nntp-inside-change-function nil) + (defvar nntp-connection-list nil) + (defvoo nntp-server-type nil) (defvoo nntp-connection-alist nil) (defvoo nntp-status-string "") *************** *** 381,386 **** --- 383,397 ---- (kill-buffer (process-buffer process)))) (nnoo-close-server 'nntp))) + (deffoo nntp-request-close () + (let (process) + (while (setq process (pop nntp-connection-list)) + (when (memq (process-status process) '(open run)) + (set-process-sentinel process nil) + (nntp-send-string process "QUIT")) + (when (buffer-name (process-buffer process)) + (kill-buffer (process-buffer process)))))) + (deffoo nntp-request-list (&optional server) (nntp-possibly-change-group nil server) (nntp-send-command-and-decode "\r?\n\\.\r?\n" "LIST")) *************** *** 562,567 **** --- 573,579 ---- (prog1 (caar (push (list process buffer nil) nntp-connection-alist)) + (push process nntp-connection-list) (nntp-read-server-type) (run-hooks 'nntp-server-opened-hook)) (when (buffer-name (process-buffer process)) *** pub/rgnus/lisp/ChangeLog Fri Aug 30 03:33:03 1996 --- rgnus/lisp/ChangeLog Sat Aug 31 03:36:24 1996 *************** *** 1,3 **** --- 1,42 ---- + Sat Aug 31 02:54:39 1996 Lars Magne Ingebrigtsen + + * gnus-topic.el (gnus-topic-goto-next-group): Go to the proper + group when listing. + + * gnus-start.el (gnus-get-killed-groups): Mark .newsrc as needing + saving. + + * nnmail.el (nnmail-remove-tabs): New function. + + Fri Aug 30 06:26:37 1996 Lars Magne Ingebrigtsen + + * gnus-start.el (gnus-set-default-directory): Set to directory + file name. + + * nnmail.el (nnmail-remove-list-identifiers): New function. + (nnmail-list-identifiers): New variable. + (nnmail-prepare-incoming-message-hook): New variable. + (nnmail-move-inbox): Allow nnmail-movemail-program to be a + function. + + * article.el (article-mime-decode-quoted-printable-buffer): New + function. + + * nnmail.el (nnmail-prepare-incoming-header-hook): New variable. + (nnmail-clean-whitespace-from-headers): New function. + + * nntp.el (nntp-connection-alist): New variable. + (nntp-open-connection): Use it. + (nntp-request-close): New function. + + * gnus-demon.el (timer): Required. + + * message.el (message-reply): Bugged out on wide replies. + + Fri Aug 30 03:51:39 1996 Lars Magne Ingebrigtsen + + * gnus.el: Red Gnus v0.20 is released. + Fri Aug 30 01:36:10 1996 Lars Magne Ingebrigtsen * gnus-msg.el (gnus-inews-insert-archive-gcc): Use *** pub/rgnus/texi/Makefile Sun Jul 14 16:13:46 1996 --- rgnus/texi/Makefile Sat Aug 31 02:35:49 1996 *************** *** 20,26 **** $(PERL) -n -e 'if (/\@iflatex/) { $$latex=1; } if (!$$latex) { print; } if (/\@end iflatex/) { $$latex=0; }' gnus.texi > gnus.tmptexi $(TEXI2DVI) gnus.tmptexi ! refcard.dvi: refcard.tex $(LATEX) refcard.tex clean: --- 20,26 ---- $(PERL) -n -e 'if (/\@iflatex/) { $$latex=1; } if (!$$latex) { print; } if (/\@end iflatex/) { $$latex=0; }' gnus.texi > gnus.tmptexi $(TEXI2DVI) gnus.tmptexi ! refcard.dvi: refcard.tex gnuslogo.refcard gnusref.tex $(LATEX) refcard.tex clean: *** pub/rgnus/texi/gnus.texi Fri Aug 30 03:49:05 1996 --- rgnus/texi/gnus.texi Sat Aug 31 03:15:01 1996 *************** *** 1,7 **** \input texinfo @c -*-texinfo-*- @setfilename gnus ! @settitle Red Gnus 0.20 Manual @synindex fn cp @synindex vr cp @synindex pg cp --- 1,7 ---- \input texinfo @c -*-texinfo-*- @setfilename gnus ! @settitle Red Gnus VERSION Manual @synindex fn cp @synindex vr cp @synindex pg cp *************** *** 230,236 **** @tex @titlepage ! @title Red Gnus 0.20 Manual @author by Lars Magne Ingebrigtsen @page --- 230,236 ---- @tex @titlepage ! @title Red Gnus VERSION Manual @author by Lars Magne Ingebrigtsen @page *************** *** 7938,7943 **** --- 7938,7944 ---- * Mail and Procmail:: Reading mail groups that procmail create. * Incorporating Old Mail:: What about the old mail you have? * Expiring Mail:: Getting rid of unwanted mail. + * Washing Mail:: Removing gruft from the mail you get. * Duplicates:: Dealing with duplicated mail. * Not Reading Mail:: Using mail backends for reading other files. * Choosing a Mail Backend:: Gnus can read a variety of mail formats. *************** *** 8159,8164 **** --- 8160,8169 ---- This program is executed to move mail from the user's inbox to her home directory. The default is @samp{movemail}. + This can also be a function. In that case, the function will be called + with two parameters -- the name of the inbox, and the file to be moved + to. + @item nnmail-delete-incoming @vindex nnmail-delete-incoming @cindex incoming mail files *************** *** 8228,8256 **** recursive structure where each split may contain other splits. Here are the five possible split syntaxes: ! @table @dfn ! @item GROUP ! If the split is a string, that will be taken as a group name. ! @item (FIELD VALUE SPLIT) ! If the split is a list, and the first element is a string, then that ! means that if header FIELD (a regexp) contains VALUE (also a regexp), ! then store the message as specified by SPLIT. ! ! @item (| SPLIT...) ! If the split is a list, and the first element is @code{|} (vertical ! bar), then process each SPLIT until one of them matches. A SPLIT is ! said to match if it will cause the mail message to be stored in one or ! more groups. ! ! @item (& SPLIT...) ! If the split is a list, and the first element is @code{&}, then process ! all SPLITs in the list. ! @item junk ! Junk this article. ! @end table In these splits, FIELD must match a complete field name. VALUE must match a complete word according to the fundamental mode syntax table. --- 8233,8264 ---- recursive structure where each split may contain other splits. Here are the five possible split syntaxes: ! @enumerate ! @item ! @samp{group}: If the split is a string, that will be taken as a group name. ! @item ! @code{(FIELD VALUE SPLIT)}: If the split is a list, and the first ! element is a string, then that means that if header FIELD (a regexp) ! contains VALUE (also a regexp), then store the message as specified by ! SPLIT. ! @item ! @code{(| SPLIT...)}: If the split is a list, and the first element is ! @code{|} (vertical bar), then process each SPLIT until one of them ! matches. A SPLIT is said to match if it will cause the mail message to ! be stored in one or more groups. ! ! @item ! @code{(& SPLIT...)}: If the split is a list, and the first element is ! @code{&}, then process all SPLITs in the list. ! ! @item ! @code{junk}: If the split is the symbol @code{junk}, then don't save ! this message anywhere. ! ! @end enumerate In these splits, FIELD must match a complete field name. VALUE must match a complete word according to the fundamental mode syntax table. *************** *** 8478,8483 **** --- 8486,8575 ---- with! So there! + @node Washing Mail + @subsection Washing Mail + @cindex mail washing + @cindex list server brain damage + @cindex incoming mail treatment + + Mailers and list servers are notorious for doing all sorts of really, + really stupid things with mail. ``Hey, RFC822 doesn't explicitly + prohibit us from adding the string @code{wE aRe ElItE!!!!!1!!} to the + end of all lines passing through our server, so let's do that!!!!1!'' + Yes, but RFC822 wasn't designed to be read by morons. Things that were + considered to be self-evident were not discussed. So. Here we are. + + Case in point: The German version of Microsoft Exchange adds @samp{AW: + } to the subjects of replies instead of @samp{Re: }. I could pretend to + be shocked and dismayed by this, but I haven't got the energy. It is to + laugh. + + Gnus provides a plethora of functions for washing articles while + displaying them, but it might be nicer to do the filtering before + storing the mail to disc. For that purpose, we have three hooks and + various functions that can be put in these hooks. + + @table @code + @item nnmail-prepare-incoming-hook + @vindex nnmail-prepare-incoming-hook + This hook is called before doing anything with the mail and is meant for + grand, sweeping gestures. Functions to be used include: + + @table @code + @item nnheader-ms-strip-cr + @findex nnheader-ms-strip-cr + Remove trailing carriage returns from each line. This is default on + Emacs running on MS machines. + + @end table + + @item nnmail-prepare-incoming-header-hook + @vindex nnmail-prepare-incoming-header-hook + This hook is called narrowed to each header. It can be used when + cleaning up the headers. Functions that can be used include: + + @table @code + @item nnmail-remove-leading-whitespace + @findex nnmail-remove-leading-whitespace + Clear leading white space that ``helpful'' listservs have added to the + headers too make them look nice. Aaah. + + @item nnmail-remove-list-identifiers + @findex nnmail-remove-list-identifiers + Some list servers add an identifier---for example, @samp{(idm)}---to the + beginning of all @code{Subject} headers. I'm sure that's nice for + people who use stone age mail readers. This function will remove + strings that match the @code{nnmail-list-identifiers} regexp, which can + also be a list of regexp. + + For instance, if you want to remove the @samp{(idm)} and the + @samp{nagnagnag} identifiers: + + @lisp + (setq nnmail-list-identifiers + '("(idm)" "nagnagnag")) + @end lisp + + @item nnmail-remove-tabs + @findex nnmail-remove-tabs + Translate all @samp{TAB} characters into @samp{SPACE} characters. + + @end table + + @item nnmail-prepare-incoming-message-hook + @vindex nnmail-prepare-incoming-message-hook + This hook is called narrowed to each message. Functions to be used + include: + + @table @code + @item article-de-quoted-unreadable + @findex article-de-quoted-unreadable + Decode Quoted Readable encoding. + + @end table + @end table + + @node Duplicates @subsection Duplicates *************** *** 8488,8494 **** If you are a member of a couple of mailing list, you will sometime receive two copies of the same mail. This can be quite annoying, so @code{nnmail} checks for and treats any duplicates it might find. To do ! this, it keeps a cache of old @code{Message-ID}s - @code{nnmail-message-id-cache-file}, which is @file{~/.nnmail-cache} by default. The approximate maximum number of @code{Message-ID}s stored there is controlled by the @code{nnmail-message-id-cache-length} --- 8580,8586 ---- If you are a member of a couple of mailing list, you will sometime receive two copies of the same mail. This can be quite annoying, so @code{nnmail} checks for and treats any duplicates it might find. To do ! this, it keeps a cache of old @code{Message-ID}s--- @code{nnmail-message-id-cache-file}, which is @file{~/.nnmail-cache} by default. The approximate maximum number of @code{Message-ID}s stored there is controlled by the @code{nnmail-message-id-cache-length} *** pub/rgnus/texi/ChangeLog Fri Aug 30 00:26:47 1996 --- rgnus/texi/ChangeLog Sat Aug 31 03:15:00 1996 *************** *** 1,3 **** --- 1,12 ---- + Sat Aug 31 02:55:50 1996 Lars Magne Ingebrigtsen + + * gnus.texi (Washing Mail): Addition. + + Fri Aug 30 09:10:17 1996 Lars Magne Ingebrigtsen + + * gnus.texi (Washing Mail): New. + (Fancy Mail Splitting): Change. + Fri Aug 30 00:21:59 1996 Lars Magne Ingebrigtsen * gnus.texi (Foreign Groups): Change.