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)))))))