+(eval-and-compile
+ (if (featurep 'xemacs)
+ (defalias 'mm-inline-image 'mm-inline-image-xemacs)
+ (defalias 'mm-inline-image 'mm-inline-image-emacs)))
+
+(defvar mm-w3-setup nil)
+(defun mm-setup-w3 ()
+ (unless mm-w3-setup
+ (require 'w3)
+ (w3-do-setup)
+ (require 'url)
+ (require 'w3-vars)
+ (require 'url-vars)
+ (setq mm-w3-setup t)))
+
+(defun mm-inline-text-html-render-with-w3 (handle)
+ (mm-setup-w3)
+ (let ((text (mm-get-part handle))
+ (b (point))
+ (url-standalone-mode t)
+ (url-gateway-unplugged t)
+ (w3-honor-stylesheets nil)
+ (url-current-object
+ (url-generic-parse-url (format "cid:%s" (mm-handle-id handle))))
+ (width (window-width))
+ (charset (mail-content-type-get
+ (mm-handle-type handle) 'charset)))
+ (save-excursion
+ (insert (if charset (mm-decode-string text charset) text))
+ (save-restriction
+ (narrow-to-region b (point))
+ (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
+ (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)
+ ;; Don't let w3 set the global version of
+ ;; this variable.
+ (fill-column fill-column))
+ (if (or debug-on-error debug-on-quit)
+ (w3-region (point-min) (point-max))
+ (condition-case ()
+ (w3-region (point-min) (point-max))
+ (error
+ (delete-region (point-min) (point-max))
+ (let ((b (point))
+ (charset (mail-content-type-get
+ (mm-handle-type handle) 'charset)))
+ (if (or (eq charset 'gnus-decoded)
+ (eq mail-parse-charset 'gnus-decoded))
+ (save-restriction
+ (narrow-to-region (point) (point))
+ (mm-insert-part handle)
+ (goto-char (point-max)))
+ (insert (mm-decode-string (mm-get-part handle)
+ charset))))
+ (message
+ "Error while rendering html; showing as text/plain")))))))
+ (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)))
+ (delete-region ,(point-min-marker)
+ ,(point-max-marker)))))))))
+
+(defvar mm-w3m-setup nil
+ "Whether gnus-article-mode has been setup to use emacs-w3m.")
+
+(defun mm-setup-w3m ()
+ "Setup gnus-article-mode to use emacs-w3m."
+ (unless mm-w3m-setup
+ (require 'w3m)
+ (unless (assq 'gnus-article-mode w3m-cid-retrieve-function-alist)
+ (push (cons 'gnus-article-mode 'mm-w3m-cid-retrieve)
+ w3m-cid-retrieve-function-alist))
+ (setq mm-w3m-setup t))
+ (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)))))
+
+(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)))))
+
+(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)))
+ (save-excursion
+ (insert (if charset (mm-decode-string text charset) text))
+ (save-restriction
+ (narrow-to-region b (point))
+ (unless charset
+ (goto-char (point-min))
+ (when (setq charset (w3m-detect-meta-charset))
+ (delete-region (point-min) (point-max))
+ (insert (mm-decode-string text charset))))
+ (let ((w3m-safe-url-regexp mm-w3m-safe-url-regexp)
+ w3m-force-redisplay)
+ (w3m-region (point-min) (point-max) nil charset))
+ (when (and mm-inline-text-html-with-w3m-keymap
+ (boundp 'w3m-minor-mode-map)
+ w3m-minor-mode-map)
+ (add-text-properties
+ (point-min) (point-max)
+ (list 'keymap w3m-minor-mode-map
+ ;; Put the mark meaning this part was rendered by emacs-w3m.
+ 'mm-inline-text-html-with-w3m t))))
+ (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)))
+ (delete-region ,(point-min-marker)
+ ,(point-max-marker))))))))
+
+(defun mm-links-remove-leading-blank ()
+ ;; Delete the annoying three spaces preceding each line of links
+ ;; output.
+ (goto-char (point-min))
+ (while (re-search-forward "^ " nil t)
+ (delete-region (match-beginning 0) (match-end 0))))
+
+(defun mm-inline-wash-with-file (post-func cmd &rest args)
+ (let ((file (mm-make-temp-file
+ (expand-file-name "mm" mm-tmp-directory))))
+ (let ((coding-system-for-write 'binary))
+ (write-region (point-min) (point-max) file nil 'silent))
+ (delete-region (point-min) (point-max))
+ (unwind-protect
+ (apply 'call-process cmd nil t nil (mapcar 'eval args))
+ (delete-file file))
+ (and post-func (funcall post-func))))
+
+(defun mm-inline-wash-with-stdin (post-func cmd &rest args)
+ (let ((coding-system-for-write 'binary))
+ (apply 'call-process-region (point-min) (point-max)
+ cmd t t nil args))
+ (and post-func (funcall post-func)))
+
+(defun mm-inline-render-with-file (handle post-func cmd &rest args)
+ (let ((source (mm-get-part handle)))
+ (mm-insert-inline
+ handle
+ (mm-with-unibyte-buffer
+ (insert source)
+ (apply 'mm-inline-wash-with-file post-func cmd args)
+ (buffer-string)))))
+
+(defun mm-inline-render-with-stdin (handle post-func cmd &rest args)
+ (let ((source (mm-get-part handle)))
+ (mm-insert-inline
+ handle
+ (mm-with-unibyte-buffer
+ (insert source)
+ (apply 'mm-inline-wash-with-stdin post-func cmd args)
+ (buffer-string)))))
+
+(defun mm-inline-render-with-function (handle func &rest args)
+ (let ((source (mm-get-part handle))
+ (charset (mail-content-type-get (mm-handle-type handle) 'charset)))
+ (mm-insert-inline
+ handle
+ (mm-with-multibyte-buffer
+ (insert (if charset
+ (mm-decode-string source charset)
+ source))
+ (apply func args)
+ (buffer-string)))))
+
+(defun mm-inline-text-html (handle)
+ (let* ((func (or mm-inline-text-html-renderer mm-text-html-renderer))
+ (entry (assq func mm-text-html-renderer-alist))
+ buffer-read-only)
+ (if entry
+ (setq func (cdr entry)))