1 ;;; gnus-picons.el: Icon hacks for displaying pretty icons in Gnus.
2 ;; Copyright (C) 1996 Wes Hardaker
4 ;; Author: Wes hardaker <hardaker@ece.ucdavis.edu>
5 ;; Keywords: gnus xpm annotation glyph faces
10 ;; - You must have XEmacs (19.12 or above I think) to use this.
11 ;; - Read the variable descriptions below.
15 ;; 1) display the icons in its own buffer:
17 ;; (add-hook 'gnus-article-display-hook 'gnus-article-display-picons t)
18 ;; (add-hook 'gnus-summary-display-hook 'gnus-group-display-picons t)
19 ;; (setq gnus-picons-display-where 'picons)
21 ;; Then add the picons buffer to your display configuration:
22 ;; The picons buffer needs to be at least 48 pixels high,
23 ;; which for me is 5 lines:
25 ;; (gnus-add-configuration
26 ;; '(article (vertical 1.0
29 ;; (summary .25 point)
32 ;; (gnus-add-configuration
33 ;; '(summary (vertical 1.0 (group 6)
35 ;; (summary 1.0 point))))
37 ;; 2) display the icons in the summary buffer
39 ;; (add-hook 'gnus-article-display-hook 'gnus-article-display-picons t)
40 ;; (add-hook 'gnus-summary-display-hook 'gnus-group-display-picons t)
41 ;; (setq gnus-picons-display-where 'summary)
43 ;; 3) display the icons in the article buffer
45 ;; (add-hook 'gnus-article-display-hook 'gnus-article-display-picons t)
46 ;; (add-hook 'gnus-article-display-hook 'gnus-group-display-picons t)
47 ;; (setq gnus-picons-display-where 'article)
51 ;; - I'm not even close to being a lisp expert.
52 ;; - The 't' (append) flag MUST be in the add-hook line
55 ;; - Remove the TODO section in the headers.
61 (require 'annotations)
63 (defvar gnus-picons-buffer "*Icon Buffer*"
64 "Buffer name to display the icons in if gnus-picons-display-where is 'picons.")
66 (defvar gnus-picons-display-where 'picons
67 "Where to display the group and article icons.")
69 (defvar gnus-picons-database "/usr/local/faces"
70 "Defines the location of the faces database.
71 For information on obtaining this database of pretty pictures, please
72 see http://www.cs.indiana.edu/picons/ftp/index.html" )
74 (defvar gnus-picons-news-directory "news"
75 "Sub-directory of the faces database containing the icons for newsgroups."
78 (defvar gnus-picons-user-directories '("local" "users" "usenix" "misc/MISC")
79 "List of directories to search for user faces."
82 (defvar gnus-picons-domain-directories '("domains")
83 "List of directories to search for domain faces.
84 Some people may want to add \"unknown\" to this list."
87 (setq gnus-group-annotations nil)
88 (setq gnus-article-annotations nil)
90 (defun gnus-picons-remove (plist)
91 (let ((listitem (car plist)))
92 (while (setq listitem (car plist))
93 (if (annotationp listitem)
94 (delete-annotation listitem))
95 (setq plist (cdr plist))))
98 (defun gnus-picons-remove-all ()
99 "Removes all picons from the Gnus display(s)."
101 (gnus-picons-remove gnus-article-annotations)
102 (gnus-picons-remove gnus-group-annotations)
103 (setq gnus-article-annotations nil
104 gnus-group-annotations nil)
105 (if (bufferp gnus-picons-buffer)
106 (kill-buffer gnus-picons-buffer))
109 (defun gnus-get-buffer-name (variable)
110 "Returns the buffer name associated with the contents of a variable."
111 (cond ((symbolp variable)
112 (let ((newvar (cdr (assq variable gnus-window-to-buffer))))
113 (cond ((symbolp newvar)
114 (symbol-value newvar))
115 ((stringp newvar) newvar))))
119 (defun gnus-article-display-picons ()
120 "Display faces for an author and his/her domain in gnus-picons-display-where."
122 (if (and (featurep 'xpm)
123 (or (not (fboundp 'device-type)) (equal (device-type) 'x)))
125 (let* ((iconpoint (point)) (from (mail-fetch-field "from"))
128 (string-match "\\([-_a-zA-Z0-9]+\\)@" from)
129 (match-string 1 from)))
131 (concat (gnus-picons-reverse-domain-path
133 (replace-in-string from ".*@\\([_a-zA-Z0-9-.]+\\).*"
136 (switch-to-buffer (gnus-get-buffer-name gnus-picons-display-where))
137 (beginning-of-buffer)
138 (setq iconpoint (point))
139 (if (not (looking-at "^$"))
149 (gnus-picons-remove gnus-article-annotations)
150 (setq gnus-article-annotations 'nil)
151 (if (equal username from)
152 (setq username (progn
153 (string-match "<\\([_a-zA-Z0-9-.]+\\)>" from)
154 (match-string 1 from))))
155 (mapcar '(lambda (pathpart)
156 (setq gnus-article-annotations
158 (gnus-picons-insert-face-if-exists
160 (file-name-as-directory
161 gnus-picons-database) pathpart)
162 (concat hostpath username)
164 gnus-article-annotations)))
165 gnus-picons-user-directories)
166 (mapcar '(lambda (pathpart)
167 (setq gnus-article-annotations
169 (gnus-picons-insert-face-if-exists
170 (concat (file-name-as-directory
171 gnus-picons-database) pathpart)
172 (concat hostpath "unknown")
174 gnus-article-annotations)))
175 gnus-picons-domain-directories)
176 (add-hook 'gnus-summary-exit-hook 'gnus-picons-remove-all)
179 (defun gnus-group-display-picons ()
180 "Display icons for the group in the gnus-picons-display-where buffer."
182 (if (and (featurep 'xpm)
183 (or (not (fboundp 'device-type)) (equal (device-type) 'x)))
186 ((iconpoint (point)))
187 (switch-to-buffer (gnus-get-buffer-name gnus-picons-display-where))
188 (beginning-of-buffer)
190 ((listp gnus-group-annotations)
191 (mapcar 'delete-annotation gnus-group-annotations)
192 (setq gnus-group-annotations nil))
193 ((annotationp gnus-group-annotations)
194 (delete-annotation gnus-group-annotations)
195 (setq gnus-group-annotations nil))
197 (setq iconpoint (point))
198 (if (not (looking-at "^$"))
200 (gnus-picons-remove gnus-group-annotations)
201 (setq gnus-group-annotations nil)
202 (setq gnus-group-annotations
203 (gnus-picons-insert-face-if-exists
204 (concat (file-name-as-directory gnus-picons-database)
205 gnus-picons-news-directory)
206 (concat (replace-in-string gnus-newsgroup-name "\\." "/")
209 (add-hook 'gnus-summary-exit-hook 'gnus-picons-remove-all)))))
212 (defun gnus-picons-insert-face-if-exists (path filename ipoint &optional rev)
213 "Inserts a face at point if I can find one"
214 (let ((pathfile (concat path "/" filename "/face"))
216 (replace-in-string filename
217 "[_a-zA-Z0-9-]+/\\([_A-Za-z0-9-]+\\)$" "\\1"))
220 (not (equal filename newfilename)))
221 (setq annotations (append
222 (gnus-picons-insert-face-if-exists path newfilename ipoint rev)
224 (if (eq (length annotations) (length (setq annotations (append
225 (gnus-picons-try-to-find-face (concat pathfile ".xpm") ipoint)
227 (setq annotations (append
228 (gnus-picons-try-to-find-face
229 (concat pathfile ".xbm") ipoint)
232 (not (equal filename newfilename)))
233 (setq annotations (append
234 (gnus-picons-insert-face-if-exists path newfilename ipoint rev)
241 (defun gnus-picons-try-to-find-face (path ipoint)
242 "If PATH exists, display it as a bitmap. Returns t if succedded."
243 (if (file-exists-p path)
245 ; (insert (format "yes: %s\n" path))
246 (setq gl (make-glyph path))
247 (set-glyph-face gl 'default)
248 (list (make-annotation gl ipoint 'text)))
249 ; (insert (format "no: %s\n" path))
252 (defun gnus-picons-reverse-domain-path (str)
254 (if (equal (replace-in-string str "^[^/]*$" "") "")
256 (concat (replace-in-string str "^.*/\\([_a-zA-Z0-9-]+\\)$" "\\1") "/"
257 (gnus-picons-reverse-domain-path
258 (replace-in-string str "^\\(.*\\)/[_a-zA-Z0-9-]+$" "\\1")))))