tm 7.67.
[elisp/tm.git] / gnus / tm-sgnus.el
1 ;;;
2 ;;; tm-sgnus.el --- MIME extender for Gnus 5.2
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.69 $
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-sgnus.el,v 7.69 1996/06/09 06:57:33 morioka Exp $")
46
47 (defconst tm-gnus/version
48   (concat (get-version-string tm-gnus/RCS-ID) " for September"))
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)
118                               mime/default-coding-system)
119   (mime/decode-message-header)
120   )
121
122 (set-alist 'mime-viewer/content-header-filter-alist
123            'gnus-original-article-mode
124            (function tm-gnus/content-header-filter))
125
126 (set-alist 'mime-viewer/code-converter-alist
127            'gnus-original-article-mode
128            (function mime-charset-decode-region))
129
130 (defun mime-viewer/quitting-method-for-sgnus ()
131   (if (not gnus-show-mime)
132       (mime-viewer/kill-buffer))
133   (delete-other-windows)
134   (gnus-article-show-summary)
135   (if (or (not gnus-show-mime)
136           (null gnus-have-all-headers))
137       (gnus-summary-select-article nil t)
138     ))
139
140 (set-alist 'mime-viewer/quitting-method-alist
141            'gnus-original-article-mode
142            (function mime-viewer/quitting-method-for-sgnus))
143 (set-alist 'mime-viewer/show-summary-method
144            'gnus-original-article-mode
145            (function mime-viewer/quitting-method-for-sgnus))
146
147
148 ;;; @ for tm-edit
149 ;;;
150
151 ;; suggested by OKABE Yasuo <okabe@kudpc.kyoto-u.ac.jp>
152 ;;      1995/11/08 (c.f. [tm ML:1067])
153 (defun tm-gnus/insert-article (&optional message)
154   (interactive)
155   (let ((message-cite-function 'mime-editor/inserted-message-filter)
156         (message-reply-buffer gnus-original-article-buffer)
157         )
158     (message-yank-original nil)
159     ))
160
161 ;;; modified by Steven L. Baur <steve@miranova.com>
162 ;;;     1995/12/6 (c.f. [tm-en:209])
163 (defun mime-editor/attach-to-news-reply-menu ()
164   "Arrange to attach MIME editor's popup menu to VM's"
165   (if (boundp 'news-reply-menu)
166       (progn
167         (setq news-reply-menu (append news-reply-menu
168                                       '("---")
169                                       mime-editor/popup-menu-for-xemacs))
170         (remove-hook 'news-setup-hook
171                      'mime-editor/attach-to-news-reply-menu)
172         )))
173
174 (call-after-loaded
175  'tm-edit
176  (function
177   (lambda ()
178     (set-alist 'mime-editor/message-inserter-alist
179                'message-mode (function tm-gnus/insert-article))
180     (if (string-match "XEmacs\\|Lucid" emacs-version)
181         (add-hook 'news-setup-hook 'mime-editor/attach-to-news-reply-menu)
182       )
183
184     (set-alist 'mime-editor/split-message-sender-alist
185                'message-mode
186                (lambda ()
187                  (interactive)
188                  (let (message-send-hook
189                        message-sent-message-via)
190                    (message-send)
191                    )))
192     )))
193
194
195 ;;; @ for tm-partial
196 ;;;
197
198 (defun tm-gnus/partial-preview-function ()
199   (tm-gnus/view-message (gnus-summary-article-number))
200   )
201
202 (call-after-loaded
203  'tm-partial
204  (lambda ()
205    (set-atype 'mime/content-decoding-condition
206               '((type . "message/partial")
207                 (method . mime-article/grab-message/partials)
208                 (major-mode . gnus-original-article-mode)
209                 (summary-buffer-exp . gnus-summary-buffer)
210                 ))
211    (set-alist 'tm-partial/preview-article-method-alist
212               'gnus-original-article-mode
213               'tm-gnus/partial-preview-function)
214    ))
215
216
217 ;;; @ article filter
218 ;;;
219
220 (defun tm-gnus/article-reset-variable ()
221   (setq tm-gnus/automatic-mime-preview nil)
222   )
223
224 (add-hook 'gnus-article-prepare-hook 'tm-gnus/article-reset-variable)
225
226 (defun tm-gnus/preview-article ()
227   (make-local-variable 'tm:mother-button-dispatcher)
228   (setq tm:mother-button-dispatcher
229         (function gnus-article-push-button))
230   (let ((mime-viewer/ignored-field-regexp "^:$")
231         (mime/default-coding-system
232          (save-excursion
233            (set-buffer gnus-summary-buffer)
234            mime/default-coding-system)))
235     (mime/viewer-mode nil nil nil gnus-original-article-buffer
236                       gnus-article-buffer)
237     )
238   (setq tm-gnus/automatic-mime-preview t)
239   (run-hooks 'tm-gnus/article-prepare-hook)
240   )
241
242 (setq gnus-show-mime-method (function tm-gnus/preview-article))
243
244 (defun tm-gnus/article-decode-encoded-word ()
245   (character-decode-region (point-min)(point-max)
246                            (save-excursion
247                              (set-buffer gnus-summary-buffer)
248                              mime/default-coding-system))
249   (mime/decode-message-header)
250   (run-hooks 'tm-gnus/article-prepare-hook)
251   )
252
253 (setq gnus-decode-encoded-word-method
254       (function tm-gnus/article-decode-encoded-word))
255
256
257 ;;; @ for MULE
258 ;;;
259
260 (defvar gnus-newsgroup-default-coding-system-alist nil)
261
262 (defun gnus-set-newsgroup-default-coding-system (ng cs)
263   "Define CS as default coding system for newsgroup NG."
264   (set-alist 'gnus-newsgroup-default-coding-system-alist
265              (concat "^" (regexp-quote ng) "\\($\\|\\.\\)")
266              cs))
267
268 (cond
269  ((featurep 'mule)
270   (cond ((boundp 'MULE)
271          (define-service-coding-system gnus-nntp-service nil *noconv*)
272          (if (and (boundp 'nntp-server-process)
273                   (processp nntp-server-process)
274                   )
275              (set-process-coding-system nntp-server-process *noconv* *noconv*)
276            )
277          )
278         (running-xemacs-20
279          (if (and (boundp 'nntp-server-process)
280                   (processp nntp-server-process)
281                   )
282              (set-process-input-coding-system nntp-server-process 'noconv)
283            )
284          ))
285   (call-after-loaded
286    'nnheader
287    (lambda ()
288      (defun nnheader-find-file-noselect (filename &optional nowarn rawfile)
289        (let ((file-coding-system-for-read *noconv*))
290          (find-file-noselect filename nowarn rawfile)
291          ))
292      (defun nnheader-insert-file-contents-literally
293        (filename &optional visit beg end replace)
294        (let ((file-coding-system-for-read *noconv*))
295          (insert-file-contents-literally filename visit beg end replace)
296          ))
297      ))
298   ;; Please use Gnus 5.2.10 or later if you use Mule.
299   (call-after-loaded
300    'nnmail
301    (lambda ()
302      (defun nnmail-find-file (file)
303        "Insert FILE in server buffer safely. [tm-sgnus.el]"
304        (set-buffer nntp-server-buffer)
305        (erase-buffer)
306        (let ((format-alist nil)
307              (after-insert-file-functions   ; for jam-code-guess
308               (if (memq 'jam-code-guess-after-insert-file-function
309                         after-insert-file-functions)
310                   '(jam-code-guess-after-insert-file-function)))
311              (file-coding-system-for-read *noconv*))
312          (condition-case ()
313              (progn (insert-file-contents file) t)
314            (file-error nil))))
315      ))
316   (defun tm-gnus/prepare-save-mail-function ()
317     (setq file-coding-system *noconv*)
318     )
319   (add-hook 'nnmail-prepare-save-mail-hook
320             'tm-gnus/prepare-save-mail-function)
321   
322   (gnus-set-newsgroup-default-coding-system "alt.chinese.text"      *hz*)
323   (gnus-set-newsgroup-default-coding-system "alt.chinese.text.big5" *big5*)
324   (gnus-set-newsgroup-default-coding-system "han"    *euc-kr*)
325   (and (boundp '*koi8*)
326        (gnus-set-newsgroup-default-coding-system "relcom" *koi8*))
327   ))
328
329
330 ;;; @ summary filter
331 ;;;
332
333 (defun tm-gnus/decode-summary-from-and-subjects ()
334   (let ((rest gnus-newsgroup-default-coding-system-alist)
335         cell)
336     (catch 'tag
337       (while (setq cell (car rest))
338         (if (string-match (car cell) gnus-newsgroup-name)
339             (throw 'tag
340                    (progn
341                      (make-local-variable 'mime/default-coding-system)
342                      (setq mime/default-coding-system (cdr cell))
343                      )))
344         (setq rest (cdr rest))
345         )))
346   (mapcar
347    (lambda (header)
348      (let ((from (or (mail-header-from header) ""))
349            (subj (or (mail-header-subject header) ""))
350            (method (car gnus-current-select-method))
351            )
352        (if (eq method 'nntp)
353            (progn
354              (setq from
355                    (character-decode-string from mime/default-coding-system))
356              (setq subj
357                    (character-decode-string subj mime/default-coding-system))
358              ))
359        (mail-header-set-from
360         header (mime-eword/decode-string from))
361        (mail-header-set-subject
362         header (mime-eword/decode-string subj))
363        ))
364    gnus-newsgroup-headers))
365      
366 (or (boundp 'nnheader-encoded-words-decoding)
367     (add-hook 'gnus-select-group-hook
368               'tm-gnus/decode-summary-from-and-subjects)
369     )
370
371
372 ;;; @ for BBDB
373 ;;;
374
375 (call-after-loaded
376  'bbdb
377  (lambda ()
378    (require 'tm-bbdb)
379    ))
380
381 (autoload 'tm-bbdb/update-record "tm-bbdb")
382
383 (defun tm-gnus/bbdb-setup ()
384   (if (memq 'bbdb/gnus-update-record gnus-article-prepare-hook)
385       (progn
386         (remove-hook 'gnus-article-prepare-hook 'bbdb/gnus-update-record)
387         (add-hook 'gnus-article-display-hook 'tm-bbdb/update-record)
388         )))
389
390 (add-hook 'gnus-startup-hook 'tm-gnus/bbdb-setup t)
391
392 (tm-gnus/bbdb-setup)
393
394
395 ;;; @ end
396 ;;;
397
398 (provide 'tm-sgnus)
399
400 ;;; tm-sgnus.el ends here