mm-view.el (mm-inline-image-emacs): Indent.
[gnus] / lisp / mm-view.el
index 316284b..9264228 100644 (file)
@@ -1,71 +1,79 @@
 ;;; 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)
+