;;; mm-view.el --- functions for viewing MIME objects
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
-;; 2004 Free Software Foundation, Inc.
+
+;; Copyright (C) 1998-2011 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
+;; For Emacs <22.2 and XEmacs.
+(eval-and-compile
+ (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
(eval-when-compile (require 'cl))
(require 'mail-parse)
(require 'mailcap)
(require 'mm-bodies)
(require 'mm-decode)
-
-(eval-and-compile
- (autoload 'gnus-article-prepare-display "gnus-art")
- (autoload 'vcard-parse-string "vcard")
- (autoload 'vcard-format-string "vcard")
- (autoload 'fill-flowed "flow-fill")
- (autoload 'html2text "html2text"))
+(require 'smime)
+(require 'mml-smime)
+
+(autoload 'gnus-completing-read "gnus-util")
+(autoload 'gnus-window-inside-pixel-edges "gnus-ems")
+(autoload 'gnus-article-prepare-display "gnus-art")
+(autoload 'vcard-parse-string "vcard")
+(autoload 'vcard-format-string "vcard")
+(autoload 'fill-flowed "flow-fill")
+(autoload 'html2text "html2text" nil t)
+
+(defvar gnus-article-mime-handles)
+(defvar gnus-newsgroup-charset)
+(defvar smime-keys)
+(defvar w3m-cid-retrieve-function-alist)
+(defvar w3m-current-buffer)
+(defvar w3m-display-inline-images)
+(defvar w3m-minor-mode-map)
(defvar mm-text-html-renderer-alist
- '((w3 . mm-inline-text-html-render-with-w3)
+ '((shr . mm-shr)
+ (w3 . mm-inline-text-html-render-with-w3)
(w3m . mm-inline-text-html-render-with-w3m)
- (w3m-standalone mm-inline-render-with-stdin nil
- "w3m" "-dump" "-T" "text/html")
+ (w3m-standalone . mm-inline-text-html-render-with-w3m-standalone)
+ (gnus-w3m . gnus-article-html)
(links mm-inline-render-with-file
mm-links-remove-leading-blank
"links" "-dump" file)
- (lynx mm-inline-render-with-stdin nil
- "lynx" "-dump" "-force_html" "-stdin" "-nolist")
- (html2text mm-inline-render-with-function html2text))
+ (lynx mm-inline-render-with-stdin nil
+ "lynx" "-dump" "-force_html" "-stdin" "-nolist")
+ (html2text mm-inline-render-with-function html2text))
"The attributes of renderer types for text/html.")
-(defvar mm-text-html-washer-alist
- '((w3 . gnus-article-wash-html-with-w3)
- (w3m . gnus-article-wash-html-with-w3m)
- (w3m-standalone mm-inline-wash-with-stdin nil
- "w3m" "-dump" "-T" "text/html")
- (links mm-inline-wash-with-file
- mm-links-remove-leading-blank
- "links" "-dump" file)
- (lynx mm-inline-wash-with-stdin nil
- "lynx" "-dump" "-force_html" "-stdin" "-nolist")
- (html2text html2text))
- "The attributes of washer types for text/html.")
-
(defcustom mm-fill-flowed t
"If non-nil a format=flowed article will be displayed flowed."
:type 'boolean
+ :version "22.1"
+ :group 'mime-display)
+
+(defcustom mm-inline-large-images-proportion 0.9
+ "Maximum proportion of large image resized when
+`mm-inline-large-images' is set to resize."
+ :type 'float
+ :version "24.1"
:group 'mime-display)
;;; Internal variables.
;;; Functions for displaying various formats inline
;;;
+(autoload 'gnus-rescale-image "gnus-util")
+
(defun mm-inline-image-emacs (handle)
(let ((b (point-marker))
- buffer-read-only)
- (put-image (mm-get-image handle) b)
+ (inhibit-read-only t))
+ (put-image
+ (let ((image (mm-get-image handle)))
+ (if (eq mm-inline-large-images 'resize)
+ (gnus-rescale-image
+ image
+ (let ((edges (gnus-window-inside-pixel-edges
+ (get-buffer-window (current-buffer)))))
+ (cons (truncate (* mm-inline-large-images-proportion
+ (- (nth 2 edges) (nth 0 edges))))
+ (truncate (* mm-inline-large-images-proportion
+ (- (nth 3 edges) (nth 1 edges)))))))
+ image))
+ b)
+ (insert "\n\n")
(mm-handle-set-undisplayer
handle
`(lambda ()
(let ((b ,b)
- buffer-read-only)
+ (inhibit-read-only t))
(remove-images b b)
(delete-region b (+ b 2)))))))
(defun mm-inline-image-xemacs (handle)
- (insert "\n\n")
- (forward-char -2)
- (let ((annot (make-annotation (mm-get-image handle) nil 'text))
- buffer-read-only)
- (mm-handle-set-undisplayer
- handle
- `(lambda ()
- (let ((b ,(point-marker))
- buffer-read-only)
- (delete-annotation ,annot)
- (delete-region (- b 2) b))))
- (set-extent-property annot 'mm t)
- (set-extent-property annot 'duplicable t)))
+ (when (featurep 'xemacs)
+ (insert "\n\n")
+ (forward-char -2)
+ (let ((annot (make-annotation (mm-get-image handle) nil 'text))
+ (inhibit-read-only t))
+ (mm-handle-set-undisplayer
+ handle
+ `(lambda ()
+ (let ((b ,(point-marker))
+ (inhibit-read-only t))
+ (delete-annotation ,annot)
+ (delete-region (- b 2) b))))
+ (set-extent-property annot 'mm t)
+ (set-extent-property annot 'duplicable t))))
(eval-and-compile
(if (featurep 'xemacs)
(defalias 'mm-inline-image 'mm-inline-image-xemacs)
(defalias 'mm-inline-image 'mm-inline-image-emacs)))
+;; External.
+(declare-function w3-do-setup "ext:w3" ())
+(declare-function w3-region "ext:w3-display" (st nd))
+(declare-function w3-prepare-buffer "ext:w3-display" (&rest args))
+
(defvar mm-w3-setup nil)
(defun mm-setup-w3 ()
(unless mm-w3-setup
(charset (mail-content-type-get
(mm-handle-type handle) 'charset)))
(save-excursion
- (insert text)
+ (insert (if charset (mm-decode-string text charset) text))
(save-restriction
(narrow-to-region b (point))
- (goto-char (point-min))
- (if (or (and (boundp 'w3-meta-content-type-charset-regexp)
- (re-search-forward
- w3-meta-content-type-charset-regexp nil t))
- (and (boundp 'w3-meta-charset-content-type-regexp)
- (re-search-forward
- w3-meta-charset-content-type-regexp nil t)))
+ (unless charset
+ (goto-char (point-min))
+ (when (or (and (boundp 'w3-meta-content-type-charset-regexp)
+ (re-search-forward
+ w3-meta-content-type-charset-regexp nil t))
+ (and (boundp 'w3-meta-charset-content-type-regexp)
+ (re-search-forward
+ w3-meta-charset-content-type-regexp nil t)))
(setq charset
- (or (let ((bsubstr (buffer-substring-no-properties
- (match-beginning 2)
- (match-end 2))))
- (if (fboundp 'w3-coding-system-for-mime-charset)
- (w3-coding-system-for-mime-charset bsubstr)
- (mm-charset-to-coding-system bsubstr)))
- charset)))
- (delete-region (point-min) (point-max))
- (insert (mm-decode-string text charset))
+ (let ((bsubstr (buffer-substring-no-properties
+ (match-beginning 2)
+ (match-end 2))))
+ (if (fboundp 'w3-coding-system-for-mime-charset)
+ (w3-coding-system-for-mime-charset bsubstr)
+ (mm-charset-to-coding-system bsubstr))))
+ (delete-region (point-min) (point-max))
+ (insert (mm-decode-string text charset))))
(save-window-excursion
(save-restriction
(let ((w3-strict-width width)
(mm-handle-set-undisplayer
handle
`(lambda ()
- (let (buffer-read-only)
- (if (functionp 'remove-specifier)
- (mapcar (lambda (prop)
- (remove-specifier
- (face-property 'default prop)
- (current-buffer)))
- '(background background-pixmap foreground)))
+ (let ((inhibit-read-only t))
+ ,@(if (functionp 'remove-specifier)
+ '((dolist (prop '(background background-pixmap foreground))
+ (remove-specifier
+ (face-property 'default prop)
+ (current-buffer)))))
(delete-region ,(point-min-marker)
,(point-max-marker)))))))))
(defvar mm-w3m-setup nil
"Whether gnus-article-mode has been setup to use emacs-w3m.")
+;; External.
+(declare-function w3m-detect-meta-charset "ext:w3m" ())
+(declare-function w3m-region "ext:w3m" (start end &optional url charset))
+
(defun mm-setup-w3m ()
"Setup gnus-article-mode to use emacs-w3m."
(unless mm-w3m-setup
(setq w3m-display-inline-images mm-inline-text-html-with-images))
(defun mm-w3m-cid-retrieve-1 (url handle)
- (if (mm-multiple-handles handle)
- (dolist (elem handle)
- (mm-w3m-cid-retrieve-1 url elem))
- (when (and (listp handle)
- (equal url (mm-handle-id handle)))
- (mm-insert-part handle)
- (throw 'found-handle (mm-handle-media-type handle)))))
+ (dolist (elem handle)
+ (when (consp elem)
+ (when (equal url (mm-handle-id elem))
+ (mm-insert-part elem)
+ (throw 'found-handle (mm-handle-media-type elem)))
+ (when (and (stringp (car elem))
+ (equal "multipart" (mm-handle-media-supertype elem)))
+ (mm-w3m-cid-retrieve-1 url elem)))))
(defun mm-w3m-cid-retrieve (url &rest args)
"Insert a content pointed by URL if it has the cid: scheme."
(when (string-match "\\`cid:" url)
- (catch 'found-handle
- (mm-w3m-cid-retrieve-1 (concat "<" (substring url (match-end 0)) ">")
- (with-current-buffer w3m-current-buffer
- gnus-article-mime-handles)))))
+ (or (catch 'found-handle
+ (mm-w3m-cid-retrieve-1
+ (setq url (concat "<" (substring url (match-end 0)) ">"))
+ (with-current-buffer w3m-current-buffer
+ gnus-article-mime-handles)))
+ (prog1
+ nil
+ (message "Failed to find \"Content-ID: %s\"" url)))))
(defun mm-inline-text-html-render-with-w3m (handle)
"Render a text/html part using emacs-w3m."
(mm-setup-w3m)
(let ((text (mm-get-part handle))
(b (point))
- (charset (mail-content-type-get (mm-handle-type handle) 'charset)))
+ (charset (or (mail-content-type-get (mm-handle-type handle) 'charset)
+