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.
37 (luna-define-class mime-elmo-buffer-entity (mime-buffer-entity) ())
38 (luna-define-class mime-elmo-imap-entity (mime-imap-entity) ()))
41 (provide 'mmelmo-imap)
42 (provide 'mmelmo-buffer)
44 (defvar elmo-message-ignored-field-list mime-view-ignored-field-list)
45 (defvar elmo-message-visible-field-list mime-view-visible-field-list)
46 (defvar elmo-message-sorted-field-list nil)
47 (defvar elmo-mime-display-header-analysis t)
49 (defcustom elmo-mime-header-max-column fill-column
50 "*Header max column number. Default is `fill-colmn'.
51 If a symbol of function is specified, the function is called and its return
53 :type '(choice (integer :tag "Column Number")
54 (function :tag "Function"))
57 (luna-define-method initialize-instance :after ((entity mime-elmo-buffer-entity)
61 (luna-define-method initialize-instance :around ((entity mime-elmo-imap-entity)
63 (luna-call-next-method))
65 ;;; Insert sorted header.
66 (defsubst elmo-mime-insert-header-from-buffer (buffer
68 &optional invisible-fields
71 (let ((the-buf (current-buffer))
72 (mode-obj (mime-find-field-presentation-method 'wide))
74 f-b p f-e field-name field field-body
75 vf-alist (sl sort-fields))
79 (narrow-to-region start end)
81 (while (re-search-forward std11-field-head-regexp nil t)
82 (setq f-b (match-beginning 0)
84 field-name (buffer-substring f-b p)
85 f-e (std11-field-end))
86 (when (mime-visible-field-p field-name
87 visible-fields invisible-fields)
89 (capitalize (buffer-substring f-b (1- p))))
90 field-body (buffer-substring p f-e)
92 (if elmo-mime-display-header-analysis
93 (inline (mime-find-field-decoder-internal
95 (inline (lambda (x y z) x))))
96 (setq vf-alist (append (list
98 (list field-body field-decoder)))
103 (function (lambda (s d)
108 (while (setq re (nth n sl))
110 (and (string-match re sf)
112 (and (string-match re df)
115 (with-current-buffer the-buf
117 (let* ((vf (car vf-alist))
118 (field-name (car vf))
119 (field-body (car (cdr vf)))
120 (field-decoder (car (cdr (cdr vf)))))
122 (insert (if field-decoder
123 (funcall field-decoder field-body
124 (string-width field-name)
125 (if (functionp elmo-mime-header-max-column)
126 (funcall elmo-mime-header-max-column)
127 elmo-mime-header-max-column))
131 (setq vf-alist (cdr vf-alist)))
132 (run-hooks 'mmelmo-header-inserted-hook))))))
134 (luna-define-generic elmo-mime-insert-sorted-header (entity
135 &optional invisible-fields
138 "Insert sorted header fields of the ENTITY.")
140 (luna-define-method elmo-mime-insert-sorted-header ((entity
141 mime-elmo-buffer-entity)
142 &optional invisible-fields
145 (elmo-mime-insert-header-from-buffer
146 (mime-buffer-entity-buffer-internal entity)
147 (mime-buffer-entity-header-start-internal entity)
148 (mime-buffer-entity-header-end-internal entity)
149 invisible-fields visible-fields sorted-fields))
151 (luna-define-method elmo-mime-insert-sorted-header ((entity
152 mime-elmo-imap-entity)
153 &optional invisible-fields
156 (let ((the-buf (current-buffer))
159 (insert (mime-imap-entity-header-string entity))
160 (setq buf (current-buffer)
164 (elmo-mime-insert-header-from-buffer buf p-min p-max
169 (luna-define-method mime-insert-text-content :around
170 ((entity mime-elmo-buffer-entity))
171 (luna-call-next-method)
172 (run-hooks 'elmo-message-text-content-inserted-hook))
174 (luna-define-method mime-insert-text-content :around
175 ((entity mime-elmo-imap-entity))
176 (luna-call-next-method)
177 (run-hooks 'elmo-message-text-content-inserted-hook))
179 (defun elmo-mime-insert-header (entity situation)
180 (elmo-mime-insert-sorted-header
182 elmo-message-ignored-field-list
183 elmo-message-visible-field-list
184 elmo-message-sorted-field-list)
185 (run-hooks 'elmo-message-header-inserted-hook))
187 (defun elmo-make-mime-message-location (folder number strategy rawbuf unread)
188 ;; Return the MIME message location structure.
189 ;; FOLDER is the ELMO folder structure.
190 ;; NUMBER is the number of the message in the FOLDER.
191 ;; STRATEGY is the message fetching strategy.
192 ;; RAWBUF is the output buffer for original message.
193 ;; If second optional argument UNREAD is non-nil, message is not marked
196 (eq (elmo-fetch-strategy-entireness strategy) 'section))
198 'mime-elmo-imap-location
203 (with-current-buffer rawbuf
204 (let (buffer-read-only)
207 (elmo-message-fetch folder number strategy
212 (defun elmo-mime-message-display (folder number viewbuf rawbuf original-mode
213 &optional ignore-cache unread keymap)
214 "Display MIME message.
215 A message in the FOLDER with NUMBER is displayed on the VIEWBUF using RAWBUF.
216 VIEWBUF is a view buffer and RAWBUF is a raw buffer.
217 ORIGINAL is the major mode of RAWBUF.
218 If optional argument IGNORE-CACHE is specified, existing cache is ignored.
219 If second optional argument UNREAD is specified, message is displayed but
221 Return non-nil if not entire message was fetched."
222 (let (mime-display-header-hook ; Do nothing.
223 (elmo-message-displaying t)
225 (unless (zerop (elmo-folder-length folder))
226 (setq entity (elmo-message-entity folder number)))
227 (setq strategy (if entity (elmo-find-fetch-strategy folder entity
229 (elmo-make-fetch-strategy 'entire)))
230 (mime-display-message
233 (eq (elmo-fetch-strategy-entireness strategy) 'section))
236 (elmo-make-mime-message-location
237 folder number strategy rawbuf unread))
241 (or (elmo-fetch-strategy-use-cache strategy)
242 (eq (elmo-fetch-strategy-entireness strategy)
245 (defun elmo-mime-display-as-is (folder number viewbuf rawbuf original-mode
246 &optional ignore-cache unread keymap)
247 "Display MIME message.
248 A message in the FOLDER with NUMBER is displayed on the VIEWBUF using RAWBUF.
249 VIEWBUF is a view buffer and RAWBUF is a raw buffer.
250 ORIGINAL is the major mode of RAWBUF.
251 If optional argument IGNORE-CACHE is specified, existing cache is ignored.
252 If second optional argument UNREAD is specified, message is displayed but
254 Return non-nil if cache is used."
255 (let (mime-display-header-hook ; Do nothing.
256 (elmo-message-displaying t)
257 entity cache-file cache-used)
258 (unless (zerop (elmo-folder-length folder))
259 (setq entity (elmo-message-entity folder number)))
263 (elmo-message-entity-field entity 'message-id)))
264 ;; Required to be an entire cache.
265 (unless (eq (elmo-file-cache-status cache-file) 'entire)
266 (setq ignore-cache t)))
267 (elmo-mime-display-as-is-internal
270 (elmo-make-mime-message-location
272 (elmo-make-fetch-strategy 'entire
277 (elmo-file-cache-status cache-file))))
278 (elmo-message-use-cache-p folder number)
280 (elmo-file-cache-path cache-file)))
282 viewbuf nil keymap original-mode)
285 ;; Replacement of mime-display-message.
286 (defun elmo-mime-display-as-is-internal (message
287 &optional preview-buffer
288 mother default-keymap-or-function
289 original-major-mode keymap)
290 (mime-maybe-hide-echo-buffer)
291 (let ((win-conf (current-window-configuration)))
294 (concat "*Preview-" (mime-entity-name message) "*")))
295 (or original-major-mode
296 (setq original-major-mode major-mode))
297 (let ((inhibit-read-only t))
298 (set-buffer (get-buffer-create preview-buffer))
302 (setq mime-mother-buffer mother))
303 (setq mime-preview-original-window-configuration win-conf)
304 (setq major-mode 'mime-view-mode)
305 (setq mode-name "MIME-View")
308 (set-buffer-multibyte nil)
309 (insert (mime-entity-body message))
310 (set-buffer-multibyte t)
311 (decode-coding-region (point-min) (point-max)
312 elmo-mime-display-as-is-coding-system)
313 (goto-char (point-min))
315 (goto-char (point-min))
317 (let ((method (cdr (assq original-major-mode
318 mime-header-presentation-method-alist))))
319 (if (functionp method)
320 (funcall method message nil)))
322 ;; set original major mode for mime-preview-quit
323 (put-text-property (point-min) (point-max)
325 `((major-mode . ,original-major-mode)))
326 (put-text-property (point-min) (point-max)
327 'elmo-as-is-entity message)
330 (if default-keymap-or-function
331 (mime-view-define-keymap default-keymap-or-function)
332 mime-view-mode-default-map)))
333 (goto-char (point-min))
334 (search-forward "\n\n" nil t)
335 (run-hooks 'mime-view-mode-hook)
336 (set-buffer-modified-p nil)
337 (setq buffer-read-only t)
341 (product-provide (provide 'elmo-mime) (require 'elmo-version))
343 ;; elmo-mime.el ends here