1 ;;; elmo-mime.el --- MIME module for ELMO.
3 ;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
5 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
6 ;; Keywords: mail, net news
8 ;; This file is part of ELMO (Elisp Library for Message Orchestration).
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
38 (luna-define-class elmo-mime-entity))
40 (luna-define-generic elmo-mime-entity-display-p (entity mime-mode)
41 "Return non-nil if ENTITY is able to display with MIME-MODE.
43 MIME-MODE is a symbol which is one of the following:
44 `mime' (Can display each MIME part)
45 `as-is' (Can display raw message)")
47 (luna-define-generic elmo-mime-entity-display (entity preview-buffer
51 "Display MIME message ENTITY.
52 PREVIEW-BUFFER is a view buffer.
53 Optional argument ORIGINAL-MAJOR-MODE is major-mode of representation
54 buffer of ENTITY. If it is nil, current `major-mode' is used.
55 If optional argument KEYMAP is specified,
56 use for keymap of representation buffer.")
58 (luna-define-generic elmo-mime-entity-display-as-is (entity
63 "Display MIME message ENTITY as is.
64 PREVIEW-BUFFER is a view buffer.
65 Optional argument ORIGINAL-MAJOR-MODE is major-mode of representation
66 buffer of ENTITY. If it is nil, current `major-mode' is used.
67 If optional argument KEYMAP is specified,
68 use for keymap of representation buffer.")
70 (luna-define-method elmo-mime-entity-display ((entity elmo-mime-entity)
75 (let ((elmo-message-displaying t))
76 (mime-display-message entity
80 original-major-mode)))
83 (luna-define-class mime-elmo-buffer-entity (mime-buffer-entity
85 (luna-define-class mime-elmo-imap-entity (mime-imap-entity
89 (provide 'mmelmo-imap)
90 (provide 'mmelmo-buffer)
92 (defvar elmo-message-ignored-field-list mime-view-ignored-field-list)
93 (defvar elmo-message-visible-field-list mime-view-visible-field-list)
94 (defvar elmo-message-sorted-field-list nil)
95 (defvar elmo-mime-display-header-analysis t)
97 (defcustom elmo-mime-header-max-column fill-column
98 "*Header max column number. Default is `fill-colmn'.
99 If a symbol of function is specified, the function is called and its return
101 :type '(choice (integer :tag "Column Number")
102 (function :tag "Function"))
105 (luna-define-method initialize-instance :after ((entity mime-elmo-buffer-entity)
109 (luna-define-method initialize-instance :around ((entity mime-elmo-imap-entity)
111 (luna-call-next-method))
113 ;;; Insert sorted header.
114 (defsubst elmo-mime-insert-header-from-buffer (buffer
116 &optional invisible-fields
119 (let ((the-buf (current-buffer))
120 (mode-obj (mime-find-field-presentation-method 'wide))
122 f-b p f-e field-name field field-body
123 vf-alist (sl sort-fields))
127 (narrow-to-region start end)
129 (while (re-search-forward std11-field-head-regexp nil t)
130 (setq f-b (match-beginning 0)
132 field-name (buffer-substring f-b p)
133 f-e (std11-field-end))
134 (when (mime-visible-field-p field-name
135 visible-fields invisible-fields)
137 (capitalize (buffer-substring f-b (1- p))))
138 field-body (buffer-substring p f-e)
140 (if elmo-mime-display-header-analysis
141 (inline (mime-find-field-decoder-internal
143 (inline (lambda (x y z) x))))
144 (setq vf-alist (append (list
146 (list field-body field-decoder)))
151 (function (lambda (s d)
156 (while (setq re (nth n sl))
158 (and (string-match re sf)
160 (and (string-match re df)
163 (with-current-buffer the-buf
165 (let* ((vf (car vf-alist))
166 (field-name (car vf))
167 (field-body (car (cdr vf)))
168 (field-decoder (car (cdr (cdr vf)))))
170 (insert (if field-decoder
171 (funcall field-decoder field-body
172 (string-width field-name)
173 (if (functionp elmo-mime-header-max-column)
174 (funcall elmo-mime-header-max-column)
175 elmo-mime-header-max-column))
179 (setq vf-alist (cdr vf-alist)))
180 (run-hooks 'mmelmo-header-inserted-hook))))))
182 (luna-define-generic elmo-mime-insert-sorted-header (entity
183 &optional invisible-fields
186 "Insert sorted header fields of the ENTITY.")
188 (luna-define-method elmo-mime-insert-sorted-header ((entity
189 mime-elmo-buffer-entity)
190 &optional invisible-fields
193 (elmo-mime-insert-header-from-buffer
194 (mime-buffer-entity-buffer-internal entity)
195 (mime-buffer-entity-header-start-internal entity)
196 (mime-buffer-entity-header-end-internal entity)
197 invisible-fields visible-fields sorted-fields))
199 (luna-define-method elmo-mime-insert-sorted-header ((entity
200 mime-elmo-imap-entity)
201 &optional invisible-fields
204 (let ((the-buf (current-buffer))
207 (insert (mime-imap-entity-header-string entity))
208 (setq buf (current-buffer)
212 (elmo-mime-insert-header-from-buffer buf p-min p-max
217 (luna-define-method mime-insert-text-content :around
218 ((entity mime-elmo-buffer-entity))
219 (luna-call-next-method)
220 (run-hooks 'elmo-message-text-content-inserted-hook))
222 (luna-define-method mime-insert-text-content :around
223 ((entity mime-elmo-imap-entity))
224 (luna-call-next-method)
225 (run-hooks 'elmo-message-text-content-inserted-hook))
227 (defun elmo-mime-insert-header (entity situation)
228 (elmo-mime-insert-sorted-header
230 elmo-message-ignored-field-list
231 elmo-message-visible-field-list
232 elmo-message-sorted-field-list)
233 (run-hooks 'elmo-message-header-inserted-hook))
235 ;; mime-elmo-buffer-entity
236 (luna-define-method elmo-mime-entity-display-p
237 ((entity mime-elmo-buffer-entity) mime-mode)
241 (luna-define-method elmo-mime-entity-display-as-is ((entity
242 mime-elmo-buffer-entity)
247 (elmo-mime-display-as-is-internal entity
251 original-major-mode))
253 ;; mime-elmo-imap-entity
254 (luna-define-method elmo-mime-entity-display-p
255 ((entity mime-elmo-imap-entity) mime-mode)
256 (not (eq mime-mode 'as-is)))
258 (luna-define-method elmo-mime-entity-display-as-is ((entity
259 mime-elmo-imap-entity)
264 (error "Don't support this method."))
267 (defun elmo-message-mime-entity (folder number rawbuf
269 ignore-cache unread entire)
270 "Return the mime-entity structure of the message in the FOLDER with NUMBER.
271 RAWBUF is the output buffer for original message.
272 If optional argument IGNORE-CACHE is non-nil, existing cache is ignored.
273 If second optional argument UNREAD is non-nil,
274 keep status of the message as unread.
275 If third optional argument ENTIRE is non-nil, fetch entire message at once."
276 (let ((strategy (elmo-find-fetch-strategy folder number
279 (cond ((null strategy) nil)
280 ((eq (elmo-fetch-strategy-entireness strategy) 'section)
283 (luna-make-entity 'mime-elmo-imap-location
287 :strategy strategy)))
289 (with-current-buffer rawbuf
290 (let (buffer-read-only)
292 (elmo-message-fetch folder number strategy unread)))
293 (mime-open-entity 'elmo-buffer rawbuf)))))
295 ;; Replacement of mime-display-message.
296 (defun elmo-mime-display-as-is-internal (message
297 &optional preview-buffer
298 mother default-keymap-or-function
299 original-major-mode keymap)
300 (mime-maybe-hide-echo-buffer)
301 (let ((win-conf (current-window-configuration)))
304 (concat "*Preview-" (mime-entity-name message) "*")))
305 (or original-major-mode
306 (setq original-major-mode major-mode))
307 (let ((inhibit-read-only t))
308 (set-buffer (get-buffer-create preview-buffer))
312 (setq mime-mother-buffer mother))
313 (setq mime-preview-original-window-configuration win-conf)
314 (setq major-mode 'mime-view-mode)
315 (setq mode-name "MIME-View")
318 (set-buffer-multibyte nil)
319 (insert (mime-entity-body message))
320 (set-buffer-multibyte t)
321 (decode-coding-region (point-min) (point-max)
322 elmo-mime-display-as-is-coding-system)
323 (goto-char (point-min))
325 (goto-char (point-min))
327 (let ((method (cdr (assq original-major-mode
328 mime-header-presentation-method-alist))))
329 (if (functionp method)
330 (funcall method message nil)))
332 ;; set original major mode for mime-preview-quit
333 (put-text-property (point-min) (point-max)
335 `((major-mode . ,original-major-mode)))
336 (put-text-property (point-min) (point-max)
337 'elmo-as-is-entity message)
340 (if default-keymap-or-function
341 (mime-view-define-keymap default-keymap-or-function)
342 mime-view-mode-default-map)))
343 (goto-char (point-min))
344 (search-forward "\n\n" nil t)
345 (run-hooks 'mime-view-mode-hook)
346 (set-buffer-modified-p nil)
347 (setq buffer-read-only t)
351 (product-provide (provide 'elmo-mime) (require 'elmo-version))
353 ;; elmo-mime.el ends here