6933782397ebf912cdfc2f1f7a0702474cc8cf2d
[elisp/tm.git] / gnus / tm-gnus5.el
1 ;;;
2 ;;; tm-gnus5.el --- MIME extender for Gnus 5.2 or later
3 ;;;
4 ;;; Copyright (C) 1995 Free Software Foundation, Inc.
5 ;;; Copyright (C) 1995,1996 MORIOKA Tomohiko
6 ;;;
7 ;;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
8 ;;; Maintainer: MORIOKA Tomohiko <morioka@jaist.ac.jp>
9 ;;;         and KOBAYASHI Shuhei <shuhei-k@jaist.ac.jp>
10 ;;; Created: 1995/09/24
11 ;;; Version: $Revision: 7.78 $
12 ;;; Keywords: news, MIME, multimedia, multilingual, encoded-word
13 ;;;
14 ;;; This file is part of tm (Tools for MIME).
15 ;;;
16 ;;; This program is free software; you can redistribute it and/or
17 ;;; modify it under the terms of the GNU General Public License as
18 ;;; published by the Free Software Foundation; either version 2, or
19 ;;; (at your option) any later version.
20 ;;;
21 ;;; This program is distributed in the hope that it will be useful,
22 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24 ;;; General Public License for more details.
25 ;;;
26 ;;; You should have received a copy of the GNU General Public License
27 ;;; along with This program.  If not, write to the Free Software
28 ;;; Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
29 ;;;
30 ;;; Code:
31
32 (require 'tl-str)
33 (require 'tl-list)
34 (require 'tl-misc)
35 (require 'tm-view)
36 (require 'gnus)
37
38 (eval-when-compile (require 'cl))
39
40
41 ;;; @ version
42 ;;;
43
44 (defconst tm-gnus/RCS-ID
45   "$Id: tm-gnus5.el,v 7.78 1996/07/14 16:37:27 morioka Exp $")
46
47 (defconst tm-gnus/version
48   (concat (get-version-string tm-gnus/RCS-ID) " for Gnus 5.2 or later"))
49
50
51 ;;; @ variables
52 ;;;
53
54 (defvar tm-gnus/automatic-mime-preview t
55   "*If non-nil, show MIME processed article.
56 This variable is set to `gnus-show-mime'.")
57
58 (setq gnus-show-mime tm-gnus/automatic-mime-preview)
59
60
61 ;;; @ command functions
62 ;;;
63
64 (defun tm-gnus/view-message (arg)
65   "MIME decode and play this message."
66   (interactive "P")
67   (let ((gnus-break-pages nil))
68     (gnus-summary-select-article t t)
69     )
70   (pop-to-buffer gnus-original-article-buffer t)
71   (let (buffer-read-only)
72     (if (text-property-any (point-min) (point-max) 'invisible t)
73         (remove-text-properties (point-min) (point-max)
74                                 gnus-hidden-properties)
75       ))
76   (mime/viewer-mode nil nil nil gnus-original-article-buffer
77                     gnus-article-buffer)
78   )
79
80 (defun tm-gnus/summary-scroll-down ()
81   "Scroll down one line current article."
82   (interactive)
83   (gnus-summary-scroll-up -1)
84   )
85
86 (defun tm-gnus/summary-toggle-header (&optional arg)
87   (interactive "P")
88   (if tm-gnus/automatic-mime-preview
89       (let* ((hidden
90               (save-excursion
91                 (set-buffer gnus-article-buffer)
92                 (text-property-any 
93                  (goto-char (point-min)) (search-forward "\n\n")
94                  'invisible t)
95                 ))
96              (mime-viewer/redisplay t)
97              )
98         (gnus-summary-select-article hidden t)
99         )
100     (gnus-summary-toggle-header arg))
101   )
102
103 (define-key gnus-summary-mode-map "v" (function tm-gnus/view-message))
104 (define-key gnus-summary-mode-map
105   "\e\r" (function tm-gnus/summary-scroll-down))
106 (substitute-key-definition
107  'gnus-summary-toggle-header
108  'tm-gnus/summary-toggle-header gnus-summary-mode-map)
109
110
111 ;;; @ for tm-view
112 ;;;
113
114 (defun tm-gnus/content-header-filter ()
115   (goto-char (point-min))
116   (mime-preview/cut-header)
117   (mime-charset-decode-region (point-min)(point-max) default-mime-charset)
118   (mime/decode-message-header)
119   )
120
121 (set-alist 'mime-viewer/content-header-filter-alist
122            'gnus-original-article-mode
123            (function tm-gnus/content-header-filter))
124
125 (set-alist 'mime-viewer/code-converter-alist
126            'gnus-original-article-mode
127            (function mime-charset-decode-region))
128
129 (defun mime-viewer/quitting-method-for-gnus5 ()
130   (if (not gnus-show-mime)
131       (mime-viewer/kill-buffer))
132   (delete-other-windows)
133   (gnus-article-show-summary)
134   (if (or (not gnus-show-mime)
135           (null gnus-have-all-headers))
136       (gnus-summary-select-article nil t)
137     ))
138
139 (set-alist 'mime-viewer/quitting-method-alist
140            'gnus-original-article-mode
141            (function mime-viewer/quitting-method-for-gnus5))
142 (set-alist 'mime-viewer/show-summary-method
143            'gnus-original-article-mode
144            (function mime-viewer/quitting-method-for-gnus5))
145
146
147 ;;; @ for tm-edit
148 ;;;
149
150 ;; suggested by OKABE Yasuo <okabe@kudpc.kyoto-u.ac.jp>
151 ;;      1995/11/08 (c.f. [tm ML:1067])
152 (defun tm-gnus/insert-article (&optional message)
153   (interactive)
154   (let ((message-cite-function 'mime-editor/inserted-message-filter)
155         (message-reply-buffer gnus-original-article-buffer)
156         )
157     (message-yank-original nil)
158     ))
159
160 ;;; modified by Steven L. Baur <steve@miranova.com>
161 ;;;     1995/12/6 (c.f. [tm-en:209])
162 (defun mime-editor/attach-to-news-reply-menu ()
163   "Arrange to attach MIME editor's popup menu to VM's"
164   (if (boundp 'news-reply-menu)
165       (progn
166         (setq news-reply-menu (append news-reply-menu
167                                       '("---")
168                                       mime-editor/popup-menu-for-xemacs))
169         (remove-hook 'news-setup-hook
170                      'mime-editor/attach-to-news-reply-menu)
171         )))
172
173 (call-after-loaded
174  'tm-edit
175  (function
176   (lambda ()
177     (set-alist 'mime-editor/message-inserter-alist
178                'message-mode (function tm-gnus/insert-article))
179     (if (string-match "XEmacs\\|Lucid" emacs-version)
180         (add-hook 'news-setup-hook 'mime-editor/attach-to-news-reply-menu)
181       )
182
183     (set-alist 'mime-editor/split-message-sender-alist
184                'message-mode
185                (lambda ()
186                  (interactive)
187                  (let (message-send-hook
188                        message-sent-message-via)
189                    (message-send)
190                    )))
191     )))
192
193
194 ;;; @ for tm-partial
195 ;;;
196
197 (defun tm-gnus/partial-preview-function ()
198   (tm-gnus/view-message (gnus-summary-article-number))
199   )
200
201 (call-after-loaded
202  'tm-partial
203  (lambda ()
204    (set-atype 'mime/content-decoding-condition
205               '((type . "message/partial")
206                 (method . mime-article/grab-message/partials)
207                 (major-mode . gnus-original-article-mode)
208                 (summary-buffer-exp . gnus-summary-buffer)
209                 ))
210    (set-alist 'tm-partial/preview-article-method-alist
211               'gnus-original-article-mode
212               'tm-gnus/partial-preview-function)
213    ))
214
215
216 ;;; @ article filter
217 ;;;
218
219 (defun tm-gnus/article-reset-variable ()
220   (setq tm-gnus/automatic-mime-preview nil)
221   )
222
223 (add-hook 'gnus-article-prepare-hook 'tm-gnus/article-reset-variable)
224
225 (defun tm-gnus/preview-article ()
226   (make-local-variable 'tm:mother-button-dispatcher)
227   (setq tm:mother-button-dispatcher
228         (function gnus-article-push-button))
229   (let ((mime-viewer/ignored-field-regexp "^:$")
230         (default-mime-charset
231           (save-excursion
232             (set-buffer gnus-summary-buffer)
233             default-mime-charset))
234         )
235     (mime/viewer-mode nil nil nil gnus-original-article-buffer
236                       gnus-article-buffer
237                       gnus-article-mode-map)
238     )
239   (setq tm-gnus/automatic-mime-preview t)
240   (run-hooks 'tm-gnus/article-prepare-hook)
241   )
242
243 (setq gnus-show-mime-method (function tm-gnus/preview-article))
244
245 (defun tm-gnus/article-decode-encoded-word ()
246   (decode-mime-charset-region (point-min)(point-max)
247                               (save-excursion
248                                 (set-buffer gnus-summary-buffer)
249                                 default-mime-charset))
250   (mime/decode-message-header)
251   (run-hooks 'tm-gnus/article-prepare-hook)
252   )
253
254 (setq gnus-decode-encoded-word-method
255       (function tm-gnus/article-decode-encoded-word))
256
257
258 ;;; @ for mule (Multilingual support)
259 ;;;
260
261 (defvar gnus-newsgroup-default-charset-alist nil)
262
263 (defun gnus-set-newsgroup-default-charset (newsgroup charset)
264   "Set CHARSET for the NEWSGROUP as default MIME charset."
265   (set-alist 'gnus-newsgroup-default-charset-alist
266              (concat "^" (regexp-quote newsgroup) "\\($\\|\\.\\)")
267              charset))
268
269 (cond
270  ((featurep 'mule)
271   (cond ((boundp 'MULE) ; for MULE 1.* and 2.*.
272          (define-service-coding-system gnus-nntp-service nil *noconv*)
273          (if (and (boundp 'nntp-server-process)
274                   (processp nntp-server-process)
275                   )
276              (set-process-coding-system nntp-server-process *noconv* *noconv*)
277            )
278          )
279         (running-xemacs-20 ; for XEmacs/mule.
280          (if (and (boundp 'nntp-server-process)
281                   (processp nntp-server-process)
282                   )
283              (set-process-input-coding-system nntp-server-process 'noconv)
284            )
285          ))
286   (call-after-loaded
287    'nnheader
288    (lambda ()
289      (defun nnheader-find-file-noselect (filename &optional nowarn rawfile)
290        (let ((file-coding-system-for-read *noconv*))
291          (find-file-noselect filename nowarn rawfile)
292          ))
293      (defun nnheader-insert-file-contents-literally
294        (filename &optional visit beg end replace)
295        (let ((file-coding-system-for-read *noconv*))
296          (insert-file-contents-literally filename visit beg end replace)
297          ))
298      ))
299   ;; Please use Gnus 5.2.10 or later if you use Mule.
300   (call-after-loaded
301    'nnmail
302    (lambda ()
303      (defun nnmail-find-file (file)
304        "Insert FILE in server buffer safely. [tm-gnus5.el]"
305        (set-buffer nntp-server-buffer)
306        (erase-buffer)
307        (let ((format-alist nil)
308              (after-insert-file-functions   ; for jam-code-guess
309               (if (memq 'jam-code-guess-after-insert-file-function
310                         after-insert-file-functions)
311                   '(jam-code-guess-after-insert-file-function)))
312              (file-coding-system-for-read *noconv*))
313          (condition-case ()
314              (progn (insert-file-contents file) t)
315            (file-error nil))))
316      ))
317   (defun tm-gnus/prepare-save-mail-function ()
318     (setq file-coding-system *noconv*)
319     )
320   (add-hook 'nnmail-prepare-save-mail-hook
321             'tm-gnus/prepare-save-mail-function)
322   
323   (gnus-set-newsgroup-default-charset "alt.chinese"             'hz)
324   (gnus-set-newsgroup-default-charset "alt.chinese.text.big5"   'big5)
325   (gnus-set-newsgroup-default-charset "tw"                      'big5)
326   (gnus-set-newsgroup-default-charset "hk"                      'big5)
327   (gnus-set-newsgroup-default-charset "hkstar"                  'big5)
328   (gnus-set-newsgroup-default-charset "han"                     'euc-kr)
329   (gnus-set-newsgroup-default-charset "relcom"                  'koi8-r)
330   ))
331
332
333 ;;; @ summary filter
334 ;;;
335
336 (defun tm-gnus/decode-summary-from-and-subjects ()
337   (let ((rest gnus-newsgroup-default-charset-alist)
338         cell)
339     (catch 'tag
340       (while (setq cell (car rest))
341         (if (string-match (car cell) gnus-newsgroup-name)
342             (throw 'tag
343                    (progn
344                      (make-local-variable 'default-mime-charset)
345                      (setq default-mime-charset (cdr cell))
346                      )))
347         (setq rest (cdr rest))
348         )))
349   (mapcar
350    (lambda (header)
351      (let ((from (or (mail-header-from header) ""))
352            (subj (or (mail-header-subject header) ""))
353            (method (car gnus-current-select-method))
354            )
355        (if (eq method 'nntp)
356            (progn
357              (setq from
358                    (decode-mime-charset-string from default-mime-charset))
359              (setq subj
360                    (decode-mime-charset-string subj default-mime-charset))
361              ))
362        (mail-header-set-from
363         header (mime-eword/decode-string from))
364        (mail-header-set-subject
365         header (mime-eword/decode-string subj))
366        ))
367    gnus-newsgroup-headers))
368
369 (or (boundp 'nnheader-encoded-words-decoding)
370     (add-hook 'gnus-select-group-hook
371               'tm-gnus/decode-summary-from-and-subjects)
372     )
373
374
375 ;;; @ for BBDB
376 ;;;
377
378 (call-after-loaded
379  'bbdb
380  (lambda ()
381    (require 'tm-bbdb)
382    ))
383
384 (autoload 'tm-bbdb/update-record "tm-bbdb")
385
386 (defun tm-gnus/bbdb-setup ()
387   (if (memq 'bbdb/gnus-update-record gnus-article-prepare-hook)
388       (progn
389         (remove-hook 'gnus-article-prepare-hook 'bbdb/gnus-update-record)
390         (add-hook 'gnus-article-display-hook 'tm-bbdb/update-record)
391         )))
392
393 (add-hook 'gnus-startup-hook 'tm-gnus/bbdb-setup t)
394
395 (tm-gnus/bbdb-setup)
396
397
398 ;;; @ end
399 ;;;
400
401 (provide 'tm-gnus5)
402
403 ;;; tm-gnus5.el ends here