Synch with Oort Gnus.
[elisp/gnus.git-] / lisp / mm-decode.el
index 25a6d5e..2a02fab 100644 (file)
     "message/partial" "message/external-body" "application/emacs-lisp"
     "application/pgp-signature" "application/x-pkcs7-signature"
     "application/pkcs7-signature")
-  "List of media types that are to be displayed inline."
+  "List of media types that are to be displayed inline.
+See also `mm-inline-media-tests', which says how to display a media
+type inline.  If no media test is defined, the default is to treat the
+type as plain text."
   :type '(repeat string)
   :group 'mime-display)
 
@@ -253,6 +256,21 @@ to:
   :type 'boolean
   :group 'mime-display)
 
+(defvar mm-file-name-rewrite-functions nil
+  "*List of functions used for rewriting file names of MIME parts.
+Each function takes a file name as input and returns a file name.
+
+Ready-made functions include
+`mm-file-name-delete-whitespace',
+`mm-file-name-trim-whitespace',
+`mm-file-name-collapse-whitespace',
+`mm-file-name-replace-whitespace',
+`capitalize', `downcase', `upcase', and
+`upcase-initials'.")
+
+(defvar mm-file-name-replace-whitespace nil
+  "String used for replacing whitespace characters; default is `\"_\"'.")
+
 (defcustom mm-default-directory nil
   "The default directory where mm will save files.
 If not set, `default-directory' will be used."
@@ -364,21 +382,16 @@ The original alist is not modified.  See also `destructive-alist-to-plist'."
 (defun mm-handle-set-external-undisplayer (handle function)
  "Set the undisplayer for this handle; postpone undisplaying of viewers
 for types in mm-keep-viewer-alive-types."
-  (if (mm-keep-viewer-alive-p handle)
-    (progn
-     (setq new-handle (copy-sequence handle))
-     (mm-handle-set-undisplayer new-handle function)
-     (mm-handle-set-undisplayer handle nil)
-     (push new-handle mm-postponed-undisplay-list)
-    )
-  (mm-handle-set-undisplayer handle function)
-  )
-)
+ (if (mm-keep-viewer-alive-p handle)
+     (let ((new-handle (copy-sequence handle)))
+       (mm-handle-set-undisplayer new-handle function)
+       (mm-handle-set-undisplayer handle nil)
+       (push new-handle mm-postponed-undisplay-list))
+   (mm-handle-set-undisplayer handle function)))
 
 (defun mm-destroy-postponed-undisplay-list ()
   (message "Destroying external MIME viewers")
-  (mm-destroy-parts mm-postponed-undisplay-list)
-)
+  (mm-destroy-parts mm-postponed-undisplay-list))
 
 (defun mm-dissect-buffer (&optional no-strict-mime)
   "Dissect the current buffer and return a list of MIME handles."
@@ -735,7 +748,7 @@ external if displayed external."
 (defun mm-display-inline (handle)
   (let* ((type (mm-handle-media-type handle))
         (function (cadr (mm-assoc-string-match mm-inline-media-tests type))))
-    (funcall function handle)
+    (funcall (or function #'mm-inline-text) handle)
     (goto-char (point-min))))
 
 (defun mm-assoc-string-match (alist type)
@@ -743,19 +756,6 @@ external if displayed external."
     (when (string-match (car elem) type)
       (return elem))))
 
-(defun mm-inlinable-p (handle)
-  "Say whether HANDLE can be displayed inline."
-  (let ((alist mm-inline-media-tests)
-       (type (mm-handle-media-type handle))
-       test)
-    (while alist
-      (when (string-match (caar alist) type)
-       (setq test (caddar alist)
-             alist nil)
-       (setq test (funcall test handle)))
-      (pop alist))
-    test))
-
 (defun mm-automatic-display-p (handle)
   "Say whether the user wants HANDLE to be displayed automatically."
   (let ((methods mm-automatic-display)
@@ -763,8 +763,7 @@ external if displayed external."
        method result)
     (while (setq method (pop methods))
       (when (and (not (mm-inline-override-p handle))
-                (string-match method type)
-                (mm-inlinable-p handle))
+                (string-match method type))
        (setq result t
              methods nil)))
     result))
@@ -776,8 +775,7 @@ external if displayed external."
        method result)
     (while (setq method (pop methods))
       (when (and (not (mm-inline-override-p handle))
-                (string-match method type)
-                (mm-inlinable-p handle))
+                (string-match method type))
        (setq result t
              methods nil)))
     result))
@@ -789,8 +787,7 @@ external if displayed external."
        ty)
     (catch 'found
       (while (setq ty (pop types))
-       (when (and (string-match ty type)
-                  (mm-inlinable-p handle))
+       (when (string-match ty type)
          (throw 'found t))))))
 
 (defun mm-inline-override-p (handle)
@@ -861,6 +858,35 @@ external if displayed external."
            (set-buffer cur)
            (insert-buffer-substring temp)))))))
 
+(defun mm-file-name-delete-whitespace (file-name)
+  "Remove all whitespace characters from FILE-NAME."
+  (while (string-match "\\s-+" file-name)
+    (setq file-name (replace-match "" t t file-name)))
+  file-name)
+
+(defun mm-file-name-trim-whitespace (file-name)
+  "Remove leading and trailing whitespace characters from FILE-NAME."
+  (when (string-match "\\`\\s-+" file-name)
+    (setq file-name (substring file-name (match-end 0))))
+  (when (string-match "\\s-+\\'" file-name)
+    (setq file-name (substring file-name 0 (match-beginning 0))))
+  file-name)
+
+(defun mm-file-name-collapse-whitespace (file-name)
+  "Collapse multiple whitespace characters in FILE-NAME."
+  (while (string-match "\\s-\\s-+" file-name)
+    (setq file-name (replace-match " " t t file-name)))
+  file-name)
+
+(defun mm-file-name-replace-whitespace (file-name)
+  "Replace whitespace characters in FILE-NAME with underscores.
+Set `mm-file-name-replace-whitespace' to any other string if you do not
+like underscores."
+  (let ((s (or mm-file-name-replace-whitespace "_")))
+    (while (string-match "\\s-" file-name)
+      (setq file-name (replace-match s t t file-name))))
+  file-name)
+
 (defun mm-save-part (handle)
   "Write HANDLE to a file."
   (let* ((name (mail-content-type-get (mm-handle-type handle) 'name))
@@ -868,7 +894,8 @@ external if displayed external."
                    (mm-handle-disposition handle) 'filename))
         file)
     (when filename
-      (setq filename (file-name-nondirectory filename)))
+      (setq filename (gnus-map-function mm-file-name-rewrite-functions
+                                       (file-name-nondirectory filename))))
     (setq file
          (read-file-name "Save MIME part to: "
                          (expand-file-name
@@ -901,7 +928,8 @@ external if displayed external."
          (read-string "Shell command on MIME part: " mm-last-shell-command)))
     (mm-with-unibyte-buffer
       (mm-insert-part handle)
-      (shell-command-on-region (point-min) (point-max) command nil))))
+      (let ((coding-system-for-write 'binary))
+       (shell-command-on-region (point-min) (point-max) command nil)))))
 
 (defun mm-interactively-view-part (handle)
   "Display HANDLE using METHOD."