-)
-
-(defvar gnus-picons-x-face-file-name
- (format "/tmp/picon-xface.%s.xbm" (user-login-name))
- "The name of the file in which to store the converted X-face header.")
-
-(defvar gnus-picons-convert-x-face (format "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | pbmtoxbm > %s" gnus-picons-x-face-file-name)
- "Command to convert the x-face header into a xbm file."
-)
-
-(defvar gnus-picons-file-suffixes
- (when (featurep 'x)
- (let ((types (list "xbm")))
- (when (featurep 'gif)
- (push "gif" types))
- (when (featurep 'xpm)
- (push "xpm" types))
- types))
- "List of suffixes on picon file names to try.")
-
-(defvar gnus-picons-display-article-move-p t
- "*Whether to move point to first empty line when displaying picons.
-This has only an effect if `gnus-picons-display-where' hs value article.")
-
-;;; Internal variables.
-
-(defvar gnus-group-annotations nil)
-(defvar gnus-article-annotations nil)
-(defvar gnus-x-face-annotations nil)
-
-(defun gnus-picons-remove (plist)
- (let ((listitem (car plist)))
- (while (setq listitem (car plist))
- (if (annotationp listitem)
- (delete-annotation listitem))
- (setq plist (cdr plist))))
- )
-
-(defun gnus-picons-remove-all ()
- "Removes all picons from the Gnus display(s)."
+ :type '(repeat string)
+ :group 'gnus-picon)
+
+(defcustom gnus-picon-file-types
+ (let ((types (list "xbm")))
+ (when (gnus-image-type-available-p 'gif)
+ (push "gif" types))
+ (when (gnus-image-type-available-p 'xpm)
+ (push "xpm" types))
+ types)
+ "*List of suffixes on picon file names to try."
+ :type '(repeat string)
+ :group 'gnus-picon)
+
+(defface gnus-picon-xbm-face '((t (:foreground "black" :background "white")))
+ "Face to show xbm picon in."
+ :group 'gnus-picon)
+
+(defface gnus-picon-face '((t (:foreground "black" :background "white")))
+ "Face to show picon in."
+ :group 'gnus-picon)
+
+;;; Internal variables:
+
+(defvar gnus-picon-setup-p nil)
+(defvar gnus-picon-glyph-alist nil
+ "Picon glyphs cache.
+List of pairs (KEY . GLYPH) where KEY is either a filename or an URL.")
+(defvar gnus-picon-cache nil)
+
+;;; Functions:
+
+(defsubst gnus-picon-split-address (address)
+ (setq address (split-string address "@"))
+ (if (stringp (cadr address))
+ (cons (car address) (split-string (cadr address) "\\."))
+ (if (stringp (car address))
+ (split-string (car address) "\\."))))
+
+(defun gnus-picon-find-face (address directories &optional exact)
+ (let* ((address (gnus-picon-split-address address))
+ (user (pop address))
+ (faddress address)
+ database directory result instance base)
+ (catch 'found
+ (dolist (database gnus-picon-databases)
+ (dolist (directory directories)
+ (setq address faddress
+ base (expand-file-name directory database))
+ (while address
+ (when (setq result (gnus-picon-find-image
+ (concat base "/" (mapconcat 'downcase
+ (reverse address)
+ "/")
+ "/" (downcase user) "/")))
+ (throw 'found result))
+ (if exact
+ (setq address nil)
+ (pop address)))
+ ;; Kludge to search MISC as well. But not in "news".
+ (unless (string= directory "news")
+ (when (setq result (gnus-picon-find-image
+ (concat base "/MISC/" user "/")))
+ (throw 'found result))))))))
+
+(defun gnus-picon-find-image (directory)
+ (let ((types gnus-picon-file-types)
+ found type file)
+ (while (and (not found)
+ (setq type (pop types)))
+ (setq found (file-exists-p (setq file (concat directory "face." type)))))
+ (if found
+ file
+ nil)))
+
+(defun gnus-picon-insert-glyph (glyph category)
+ "Insert GLYPH into the buffer.
+GLYPH can be either a glyph or a string."
+ (if (stringp glyph)
+ (insert glyph)
+ (gnus-add-wash-type category)
+ (gnus-add-image category (car glyph))
+ (gnus-put-image (car glyph) (cdr glyph))))
+
+(defun gnus-picon-create-glyph (file)
+ (or (cdr (assoc file gnus-picon-glyph-alist))
+ (cdar (push (cons file (gnus-create-image file))
+ gnus-picon-glyph-alist))))
+
+;;; Functions that does picon transformations:
+
+(defun gnus-picon-transform-address (header category)
+ (gnus-with-article-headers
+ (let ((addresses
+ (mail-header-parse-addresses (mail-fetch-field header)))
+ spec file point cache)
+ (dolist (address addresses)
+ (setq address (car address))
+ (when (and (stringp address)
+ (setq spec (gnus-picon-split-address address)))
+ (if (setq cache (cdr (assoc address gnus-picon-cache)))
+ (setq spec cache)
+ (when (setq file (or (gnus-picon-find-face
+ address gnus-picon-user-directories)
+ (gnus-picon-find-face
+ (concat "unknown@"
+ (mapconcat
+ 'identity (cdr spec) "."))
+ gnus-picon-user-directories)))
+ (setcar spec (cons (gnus-picon-create-glyph file)
+ (car spec))))
+
+ (dotimes (i (1- (length spec)))
+ (when (setq file (gnus-picon-find-face
+ (concat "unknown@"
+ (mapconcat
+ 'identity (nthcdr (1+ i) spec) "."))
+ gnus-picon-domain-directories t))
+ (setcar (nthcdr (1+ i) spec)
+ (cons (gnus-picon-create-glyph file)
+ (nth (1+ i) spec)))))
+ (setq spec (nreverse spec))
+ (push (cons address spec) gnus-picon-cache))
+
+ (gnus-article-goto-header header)
+ (mail-header-narrow-to-field)
+ (when (search-forward address nil t)
+ (delete-region (match-beginning 0) (match-end 0))
+ (setq point (point))
+ (while spec
+ (goto-char point)
+ (if (> (length spec) 2)
+ (insert ".")
+ (if (= (length spec) 2)
+ (insert "@")))
+ (gnus-picon-insert-glyph (pop spec) category))))))))
+
+(defun gnus-picon-transform-newsgroups (header)