Function: nnmail-article-group

nnmail-article-group is an autoloaded and byte-compiled function defined in nnmail.el.gz.

Signature

(nnmail-article-group FUNC &optional TRACE JUNK-FUNC)

Documentation

Look at the headers and return an alist of groups that match.

FUNC will be called with the group name to determine the article number.

Source Code

;; Defined in /usr/src/emacs/lisp/gnus/nnmail.el.gz
(defun nnmail-article-group (func &optional trace junk-func)
  "Look at the headers and return an alist of groups that match.
FUNC will be called with the group name to determine the article number."
  (let ((methods (or nnmail-split-methods '(("bogus" ""))))
	(obuf (current-buffer))
	group-art method grp)
    (if (and (sequencep methods)
	     (= (length methods) 1)
	     (not nnmail-inhibit-default-split-group))
	;; If there is only just one group to put everything in, we
	;; just return a list with just this one method in.
	(setq group-art
	      (list (cons (caar methods) (funcall func (caar methods)))))
      ;; We do actual comparison.
      ;; Copy the article into the work buffer.
      (with-current-buffer nntp-server-buffer
	(erase-buffer)
	(insert-buffer-substring obuf)
	;; Narrow to headers.
	(narrow-to-region
	 (goto-char (point-min))
	 (if (search-forward "\n\n" nil t)
	     (point)
	   (point-max)))
	(goto-char (point-min))
	;; Decode MIME headers and charsets.
	(when nnmail-mail-splitting-decodes
	  (let ((mail-parse-charset nnmail-mail-splitting-charset))
	    (mail-decode-encoded-word-region (point-min) (point-max))))
	;; Fold continuation lines.
	(goto-char (point-min))
	(while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
	  (replace-match " " t t))
	;; Nuke pathologically long headers.  Since Gnus applies
	;; pathologically complex regexps to the buffer, lines
	;; that are looong will take longer than the Universe's
	;; existence to process.
	(goto-char (point-min))
	(while (not (eobp))
	  (unless (< (move-to-column nnmail-split-header-length-limit)
		     nnmail-split-header-length-limit)
            (delete-region (point) (line-end-position)))
	  (forward-line 1))
	;; Allow washing.
	(goto-char (point-min))
	(run-hooks 'nnmail-split-hook)
	(when (setq nnmail-split-tracing trace)
	  (setq nnmail-split-trace nil))
	(if (or (and (symbolp nnmail-split-methods)
		     (fboundp nnmail-split-methods))
		(not (consp (car-safe nnmail-split-methods)))
		(and (listp nnmail-split-methods)
		     ;; Not a regular split method, so it has to be a
		     ;; fancy one.
		     (not (let ((top-element (car-safe nnmail-split-methods)))
			    (and (= 2 (length top-element))
				 (stringp (nth 0 top-element))
				 (stringp (nth 1 top-element)))))))
	    (let* ((method-function
		    (if (and (symbolp nnmail-split-methods)
			     (fboundp nnmail-split-methods))
			nnmail-split-methods
		      'nnmail-split-fancy))
		   (split
		    (condition-case error-info
			;; `nnmail-split-methods' is a function, so we
			;; just call this function here and use the
			;; result.
			(or (funcall method-function)
			    (and (not nnmail-inhibit-default-split-group)
				 '("bogus")))
		      (error
		       (nnheader-message
			5 "Error in `nnmail-split-methods'; using `bogus' mail group: %S" error-info)
		       (sit-for 1)
		       '("bogus")))))
	      (setq split (delete-dups split))
	      ;; The article may be "cross-posted" to `junk'.  What
	      ;; to do?  Just remove the `junk' spec.  Don't really
	      ;; see anything else to do...
	      (when (and (memq 'junk split)
			 junk-func)
		(funcall junk-func 'junk))
	      (setq split (delq 'junk split))
	      (when split
		(setq group-art
		      (mapcar
		       (lambda (group) (cons group (funcall func group)))
		       split))))
	  ;; Go through the split methods to find a match.
	  (while (and methods
		      (or nnmail-crosspost
			  (not group-art)))
	    (goto-char (point-max))
	    (setq method (pop methods)
		  grp (car method))
	    (if (or methods
		    (not (equal "" (nth 1 method))))
		(when (and
		       (ignore-errors
			 (if (stringp (nth 1 method))
			     (let ((expand (string-match "\\\\[0-9&]" grp))
				   (pos (re-search-backward (cadr method)
							    nil t)))
			       (and expand
				    (setq grp (nnmail-expand-newtext grp)))
			       pos)
			   ;; Function to say whether this is a match.
			   (funcall (nth 1 method) grp)))
		       ;; Don't enter the article into the same
		       ;; group twice.
		       (not (assoc grp group-art)))
		  (push (cons grp (funcall func grp))
			group-art))
	      ;; This is the final group, which is used as a
	      ;; catch-all.
	      (when (and (not group-art)
			 (or (equal "" (nth 1 method))
			     (not nnmail-inhibit-default-split-group)))
		(setq group-art
		      (list (cons (car method)
				  (funcall func (car method))))))))
	  ;; Fall back on "bogus" if all else fails.
	  (when (and (not group-art)
		     (not nnmail-inhibit-default-split-group))
	    (setq group-art (list (cons "bogus" (funcall func "bogus"))))))
	;; Produce a trace if non-empty.
	(when (and trace nnmail-split-trace)
	  (let ((restore (current-buffer)))
	    (nnheader-set-temp-buffer "*Split Trace*")
	    (gnus-add-buffer)
	    (dolist (trace (nreverse nnmail-split-trace))
	      (prin1 trace (current-buffer))
	      (insert "\n"))
	    (goto-char (point-min))
	    (gnus-configure-windows 'split-trace)
	    (set-buffer restore)))
	(widen)
	;; See whether the split methods returned `junk'.
	(if (equal group-art '(junk))
	    nil
	  ;; The article may be "cross-posted" to `junk'.  What
	  ;; to do?  Just remove the `junk' spec.  Don't really
	  ;; see anything else to do...
	  (let (elem)
	    (while (setq elem (car (memq 'junk group-art)))
	      (setq group-art (delq elem group-art)))
	    (nreverse group-art)))))))