;;; rmailmm.el --- MIME decoding and display stuff for RMAIL
-;; Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+;; Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: Alexander Pohoyda
;; Alex Schroeder
;; Maintainer: FSF
;; Keywords: mail
+;; Package: rmail
;; This file is part of GNU Emacs.
;; Todo:
;; Handle multipart/alternative.
+;; Offer the option to call external/internal viewers (doc-view, xpdf, etc).
;;; Code:
'(("multipart/.*" rmail-mime-multipart-handler)
("text/.*" rmail-mime-text-handler)
("text/\\(x-\\)?patch" rmail-mime-bulk-handler)
- ;; FIXME this handler not defined anywhere?
-;;; ("application/pgp-signature" rmail-mime-application/pgp-signature-handler)
("\\(image\\|audio\\|video\\|application\\)/.*" rmail-mime-bulk-handler))
"Functions to handle various content types.
This is an alist with elements of the form (REGEXP FUNCTION ...).
(defcustom rmail-mime-show-images 'button
"What to do with image attachments that Emacs is capable of displaying.
If nil, do nothing special. If `button', add an extra button
-that when pushed displays the image in the buffer. Anything else
-means to automatically display the image in the buffer."
+that when pushed displays the image in the buffer. If a number,
+automatically show images if they are smaller than that size (in
+bytes), otherwise add a display button. Anything else means to
+automatically display the image in the buffer."
:type '(choice (const :tag "Add button to view image" button)
(const :tag "No special treatment" nil)
+ (number :tag "Show if smaller than certain size")
(other :tag "Always show" show))
:version "23.2"
:group 'rmail-mime)
(file-name-as-directory filename))))
(with-temp-buffer
(set-buffer-file-coding-system 'no-conversion)
+ ;; Needed e.g. by jka-compr, so if the attachment is a compressed
+ ;; file, the magic signature compares equal with the unibyte
+ ;; signature string recorded in jka-compr-compression-info-list.
+ (set-buffer-multibyte nil)
(insert data)
(write-region nil nil filename nil nil nil t))))
(data (buffer-string))
(udata (string-as-unibyte data))
(size (length udata))
+ (osize size)
(units '(B kB MB GB))
type)
(while (and (> size 1024.0) ; cribbed from gnus-agent-expire-done-message
(memq type image-types)
(image-type-available-p type))
(insert " ")
- (cond ((eq rmail-mime-show-images 'button)
+ (cond ((or (eq rmail-mime-show-images 'button)
+ (and (numberp rmail-mime-show-images)
+ (>= osize rmail-mime-show-images)))
(insert-button "Display"
:type 'rmail-mime-image
'help-echo "mouse-2, RET: Show image"
content-transfer-encoding)))
(delete-region end next)
;; Handle the part.
- (save-match-data
- (save-excursion
- (save-restriction
- (narrow-to-region beg end)
- (rmail-mime-show))))
- (setq beg next)
- (goto-char beg))))
+ (save-restriction
+ (narrow-to-region beg end)
+ (rmail-mime-show))
+ (goto-char (setq beg next)))))
+
(defun test-rmail-mime-multipart-handler ()
"Test of a mail used as an example in RFC 2046."
point should be at the beginning of the body.
CONTENT-TYPE, CONTENT-DISPOSITION, and CONTENT-TRANSFER-ENCODING
-are the values of the respective parsed headers. The parsed
-headers for CONTENT-TYPE and CONTENT-DISPOSITION have the form
+are the values of the respective parsed headers. The latter should
+be downcased. The parsed headers for CONTENT-TYPE and CONTENT-DISPOSITION
+have the form
\(VALUE . ALIST)
(setq content-transfer-encoding nil))
((string= content-transfer-encoding "8bit")
;; FIXME: Is this the correct way?
- (set-buffer-multibyte nil)))
+ ;; No, of course not, it just means there's no decoding to do.
+ ;; (set-buffer-multibyte nil)
+ (setq content-transfer-encoding nil)
+ ))
;; Inline stuff requires work. Attachments are handled by the bulk
;; handler.
(if (string= "inline" (car content-disposition))
(mail-fetch-field "Content-Transfer-Encoding")
content-disposition
(mail-fetch-field "Content-Disposition")))))
- (if content-type
- (setq content-type (mail-header-parse-content-type
- content-type))
- ;; FIXME: Default "message/rfc822" in a "multipart/digest"
- ;; according to RFC 2046.
- (setq content-type '("text/plain")))
+ ;; Per RFC 2045, C-T-E is case insensitive (bug#5070), but the others
+ ;; are not completely so. Hopefully mail-header-parse-* DTRT.
+ (if content-transfer-encoding
+ (setq content-transfer-encoding (downcase content-transfer-encoding)))
+ (setq content-type
+ (if content-type
+ (mail-header-parse-content-type content-type)
+ ;; FIXME: Default "message/rfc822" in a "multipart/digest"
+ ;; according to RFC 2046.
+ '("text/plain")))
(setq content-disposition
(if content-disposition
(mail-header-parse-content-disposition content-disposition)
(set-buffer buf)
(setq buffer-undo-list t)
(let ((inhibit-read-only t))
+ ;; Decoding the message in fundamental mode for speed, only
+ ;; switching to rmail-mime-mode at the end for display. Eg
+ ;; quoted-printable-decode-region gets very slow otherwise (Bug#4993).
+ (fundamental-mode)
(erase-buffer)
(insert data)
- (rmail-mime-mode)
(rmail-mime-show t)
+ (rmail-mime-mode)
(set-buffer-modified-p nil))
(view-buffer buf)))