(gnus-summary-from-or-to-or-newsgroups): Check
[gnus] / lisp / mm-decode.el
index bfb7b6f..99076cc 100644 (file)
@@ -1,6 +1,7 @@
 ;;; mm-decode.el --- Functions for decoding MIME things
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
-;;        Free Software Foundation, Inc.
+
+;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+;;   2005, 2006 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>
@@ -18,8 +19,8 @@
 
 ;; 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.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
 (eval-and-compile
   (autoload 'mm-inline-partial "mm-partial")
   (autoload 'mm-inline-external-body "mm-extern")
+  (autoload 'mm-extern-cache-contents "mm-extern")
   (autoload 'mm-insert-inline "mm-view"))
 
+(defvar gnus-current-window-configuration)
+
 (add-hook 'gnus-exit-gnus-hook 'mm-destroy-postponed-undisplay-list)
 
 (defgroup mime-display ()
@@ -114,6 +118,7 @@ The defined renderer types are:
 `lynx' : use lynx;
 `html2text' : use html2text;
 nil    : use external viewer."
+  :version "22.1"
   :type '(choice (const w3)
                 (const w3m)
                 (const w3m-standalone)
@@ -122,7 +127,6 @@ nil    : use external viewer."
                 (const html2text)
                 (const nil)
                 (function))
-  :version "21.3"
   :group 'mime-display)
 
 (defvar mm-inline-text-html-renderer nil
@@ -133,6 +137,7 @@ It is suggested to customize `mm-text-html-renderer' instead.")
   "If non-nil, Gnus will allow retrieving images in HTML contents with
 the <img> tags.  It has no effect on Emacs/w3.  See also the
 documentation for the `mm-w3m-safe-url-regexp' variable."
+  :version "22.1"
   :type 'boolean
   :group 'mime-display)
 
@@ -148,12 +153,14 @@ when displaying the image.  The default value is \"\\\\`cid:\" which only
 matches parts embedded to the Multipart/Related type MIME contents and
 Gnus will never connect to the spammer's site arbitrarily.  You may
 set this variable to nil if you consider all urls to be safe."
+  :version "22.1"
   :type '(choice (regexp :tag "Regexp")
                 (const :tag "All URLs are safe" nil))
   :group 'mime-display)
 
 (defcustom mm-inline-text-html-with-w3m-keymap t
   "If non-nil, use emacs-w3m command keys in the article buffer."
+  :version "22.1"
   :type 'boolean
   :group 'mime-display)
 
@@ -163,7 +170,7 @@ set this variable to nil if you consider all urls to be safe."
 If t, all defined external MIME handlers are used.  If nil, files are saved by
 `mailcap-save-binary-file'.  If it is the symbol `ask', you are prompted
 before the external MIME handler is invoked."
-  :version "21.4"
+  :version "22.1"
   :type '(choice (const :tag "Always" t)
                 (const :tag "Never" nil)
                 (const :tag "Ask" ask))
@@ -215,9 +222,15 @@ before the external MIME handler is invoked."
     ("text/richtext" mm-inline-text identity)
     ("text/x-patch" mm-display-patch-inline
      (lambda (handle)
-       (locate-library "diff-mode")))
+       ;; If the diff-mode.el package is installed, the function is
+       ;; autoloaded.  Checking (locate-library "diff-mode") would be trying
+       ;; to cater to broken installations.  OTOH checking the function
+       ;; makes it possible to install another package which provides an
+       ;; alternative implementation of diff-mode.  --Stef
+       (fboundp 'diff-mode)))
     ("application/emacs-lisp" mm-display-elisp-inline identity)
     ("application/x-emacs-lisp" mm-display-elisp-inline identity)
+    ("text/dns" mm-display-dns-inline identity)
     ("text/html"
      mm-inline-text-html
      (lambda (handle)
@@ -267,11 +280,13 @@ before the external MIME handler is invoked."
     "application/x-emacs-lisp"
     "application/pgp-signature" "application/x-pkcs7-signature"
     "application/pkcs7-signature" "application/x-pkcs7-mime"
-    "application/pkcs7-mime")
+    "application/pkcs7-mime"
+    ;; Mutt still uses this even though it has already been withdrawn.
+    "application/pgp")
   "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."
-  :type '(repeat string)
+  :type '(repeat regexp)
   :group 'mime-display)
 
 (defcustom mm-keep-viewer-alive-types
@@ -279,19 +294,22 @@ type inline."
     "application/pdf" "application/x-dvi")
   "List of media types for which the external viewer will not be killed
 when selecting a different article."
-  :type '(repeat string)
+  :version "22.1"
+  :type '(repeat regexp)
   :group 'mime-display)
 
 (defcustom mm-automatic-display
-  '("text/plain" "text/enriched" "text/richtext" "text/html"
+  '("text/plain" "text/enriched" "text/richtext" "text/html" "text/x-verbatim"
     "text/x-vcard" "image/.*" "message/delivery-status" "multipart/.*"
-    "message/rfc822" "text/x-patch" "application/pgp-signature"
+    "message/rfc822" "text/x-patch" "text/dns" "application/pgp-signature"
     "application/emacs-lisp" "application/x-emacs-lisp"
     "application/x-pkcs7-signature"
     "application/pkcs7-signature" "application/x-pkcs7-mime"
-    "application/pkcs7-mime")
+    "application/pkcs7-mime"
+    ;; Mutt still uses this even though it has already been withdrawn.
+    "application/pgp")
   "A list of MIME types to be displayed automatically."
-  :type '(repeat string)
+  :type '(repeat regexp)
   :group 'mime-display)
 
 (defcustom mm-attachment-override-types '("text/x-vcard"
@@ -300,17 +318,17 @@ when selecting a different article."
                                          "application/pkcs7-signature"
                                          "application/x-pkcs7-signature")
   "Types to have \"attachment\" ignored if they can be displayed inline."
-  :type '(repeat string)
+  :type '(repeat regexp)
   :group 'mime-display)
 
 (defcustom mm-inline-override-types nil
   "Types to be treated as attachments even if they can be displayed inline."
-  :type '(repeat string)
+  :type '(repeat regexp)
   :group 'mime-display)
 
 (defcustom mm-automatic-external-display nil
   "List of MIME type regexps that will be displayed externally automatically."
-  :type '(repeat string)
+  :type '(repeat regexp)
   :group 'mime-display)
 
 (defcustom mm-discouraged-alternatives nil
@@ -322,8 +340,13 @@ for instance, text/html parts are very unwanted, and text/richtext are
 somewhat unwanted, then the value of this variable should be set
 to:
 
- (\"text/html\" \"text/richtext\")"
-  :type '(repeat string)
+ (\"text/html\" \"text/richtext\")
+
+Adding \"image/.*\" might also be useful.  Spammers use it as the
+prefered part of multipart/alternative messages.  See also
+`gnus-buttonized-mime-types', to which adding \"multipart/alternative\"
+enables you to choose manually one of two types those mails include."
+  :type '(repeat regexp) ;; See `mm-preferred-alternative-precedence'.
   :group 'mime-display)
 
 (defcustom mm-tmp-directory
@@ -375,11 +398,13 @@ If not set, `default-directory' will be used."
 
 (defcustom mm-attachment-file-modes 384
   "Set the mode bits of saved attachments to this integer."
+  :version "22.1"
   :type 'integer
   :group 'mime-display)
 
 (defcustom mm-external-terminal-program "xterm"
   "The program to start an external terminal."
+  :version "22.1"
   :type 'string
   :group 'mime-display)
 
@@ -412,6 +437,7 @@ If not set, `default-directory' will be used."
   "Option of verifying signed parts.
 `never', not verify; `always', always verify;
 `known', only verify known protocols.  Otherwise, ask user."
+  :version "22.1"
   :type '(choice (item always)
                 (item never)
                 (item :tag "only known protocols" known)
@@ -430,6 +456,7 @@ If not set, `default-directory' will be used."
   "Option of decrypting encrypted parts.
 `never', not decrypt; `always', always decrypt;
 `known', only decrypt known protocols.  Otherwise, ask user."
+  :version "22.1"
   :type '(choice (item always)
                 (item never)
                 (item :tag "only known protocols" known)
@@ -439,21 +466,19 @@ If not set, `default-directory' will be used."
 (defvar mm-viewer-completion-map
   (let ((map (make-sparse-keymap 'mm-viewer-completion-map)))
     (set-keymap-parent map minibuffer-local-completion-map)
+    ;; Should we bind other key to minibuffer-complete-word?
+    (define-key map " " 'self-insert-command)
     map)
   "Keymap for input viewer with completion.")
 
-;; Should we bind other key to minibuffer-complete-word?
-(define-key mm-viewer-completion-map " " 'self-insert-command)
-
 (defvar mm-viewer-completion-map
   (let ((map (make-sparse-keymap 'mm-viewer-completion-map)))
     (set-keymap-parent map minibuffer-local-completion-map)
+    ;; Should we bind other key to minibuffer-complete-word?
+    (define-key map " " 'self-insert-command)
     map)
   "Keymap for input viewer with completion.")
 
-;; Should we bind other key to minibuffer-complete-word?
-(define-key mm-viewer-completion-map " " 'self-insert-command)
-
 ;;; The functions.
 
 (defun mm-alist-to-plist (alist)
@@ -500,22 +525,23 @@ Postpone undisplaying of viewers for types in
     (message "Destroying external MIME viewers")
     (mm-destroy-parts mm-postponed-undisplay-list)))
 
-(defun mm-dissect-buffer (&optional no-strict-mime loose-mime)
+(defun mm-dissect-buffer (&optional no-strict-mime loose-mime from)
   "Dissect the current buffer and return a list of MIME handles."
   (save-excursion
-    (let (ct ctl type subtype cte cd description id result from)
+    (let (ct ctl type subtype cte cd description id result)
       (save-restriction
        (mail-narrow-to-head)
        (when (or no-strict-mime
                  loose-mime
                  (mail-fetch-field "mime-version"))
          (setq ct (mail-fetch-field "content-type")
-               ctl (ignore-errors (mail-header-parse-content-type ct))
+               ctl (and ct (mail-header-parse-content-type ct))
                cte (mail-fetch-field "content-transfer-encoding")
                cd (mail-fetch-field "content-disposition")
                description (mail-fetch-field "content-description")
-               from (mail-fetch-field "from")
                id (mail-fetch-field "content-id"))
+         (unless from
+           (setq from (mail-fetch-field "from")))
          ;; FIXME: In some circumstances, this code is running within
          ;; an unibyte macro.  mail-extract-address-components
          ;; creates unibyte buffers. This `if', though not a perfect
@@ -528,7 +554,7 @@ Postpone undisplaying of viewers for types in
           (list mm-dissect-default-type)
           (and cte (intern (downcase (mail-header-strip cte))))
           no-strict-mime
-          (and cd (ignore-errors (mail-header-parse-content-disposition cd)))
+          (and cd (mail-header-parse-content-disposition cd))
           description)
        (setq type (split-string (car ctl) "/"))
        (setq subtype (cadr type)
@@ -547,22 +573,21 @@ Postpone undisplaying of viewers for types in
             ;; what really needs to be done here is a way to link a
             ;; MIME handle back to it's parent MIME handle (in a multilevel
             ;; MIME article).  That would probably require changing
-            ;; the mm-handle API so we simply store the multipart buffert
+            ;; the mm-handle API so we simply store the multipart buffer
             ;; name as a text property of the "multipart/whatever" string.
             (add-text-properties 0 (length (car ctl))
                                  (list 'buffer (mm-copy-to-buffer)
                                        'from from
                                        'start start)
                                  (car ctl))
-            (cons (car ctl) (mm-dissect-multipart ctl))))
+            (cons (car ctl) (mm-dissect-multipart ctl from))))
          (t
           (mm-possibly-verify-or-decrypt
            (mm-dissect-singlepart
             ctl
             (and cte (intern (downcase (mail-header-strip cte))))
             no-strict-mime
-            (and cd (ignore-errors
-                      (mail-header-parse-content-disposition cd)))
+            (and cd (mail-header-parse-content-disposition cd))
             description id)
            ctl))))
        (when id
@@ -579,7 +604,7 @@ Postpone undisplaying of viewers for types in
     (mm-make-handle
      (mm-copy-to-buffer) ctl cte nil cdl description nil id)))
 
-(defun mm-dissect-multipart (ctl)
+(defun mm-dissect-multipart (ctl from)
   (goto-char (point-min))
   (let* ((boundary (concat "\n--" (mail-content-type-get ctl 'boundary)))
         (close-delimiter (concat (regexp-quote boundary) "--[ \t]*$"))
@@ -596,7 +621,7 @@ Postpone undisplaying of viewers for types in
        (save-excursion
          (save-restriction
            (narrow-to-region start (point))
-           (setq parts (nconc (list (mm-dissect-buffer t)) parts)))))
+           (setq parts (nconc (list (mm-dissect-buffer t nil from)) parts)))))
       (end-of-line 2)
       (or (looking-at boundary)
          (forward-line 1))
@@ -605,7 +630,7 @@ Postpone undisplaying of viewers for types in
       (save-excursion
        (save-restriction
          (narrow-to-region start end)
-         (setq parts (nconc (list (mm-dissect-buffer t)) parts)))))
+         (setq parts (nconc (list (mm-dissect-buffer t nil from)) parts)))))
     (mm-possibly-verify-or-decrypt (nreverse parts) ctl)))
 
 (defun mm-copy-to-buffer ()
@@ -616,7 +641,10 @@ Postpone undisplaying of viewers for types in
       (goto-char (point-min))
       (search-forward-regexp "^\n" nil t)
       (setq beg (point))
-      (set-buffer (generate-new-buffer " *mm*"))
+      (set-buffer
+       ;; Preserve the data's unibyteness (for url-insert-file-contents).
+       (let ((default-enable-multibyte-characters (mm-multibyte-p)))
+        (generate-new-buffer " *mm*")))
       (insert-buffer-substring obuf beg)
       (current-buffer))))
 
@@ -736,7 +764,18 @@ external if displayed external."
                          (gnus-map-function mm-file-name-rewrite-functions
                                             (file-name-nondirectory filename))
                          dir))
-           (setq file (mm-make-temp-file (expand-file-name "mm." dir))))
+           ;; Use nametemplate (defined in RFC1524) if it is specified
+           ;; in mailcap.
+           (let ((suffix (cdr (assoc "nametemplate" mime-info))))
+             (if (and suffix
+                      (string-match "\\`%s\\(\\..+\\)\\'" suffix))
+                 (setq suffix (match-string 1 suffix))
+               ;; Otherwise, use a suffix according to
+               ;; `mailcap-mime-extensions'.
+               (setq suffix (car (rassoc (mm-handle-media-type handle)
+                                         mailcap-mime-extensions))))
+             (setq file (mm-make-temp-file (expand-file-name "mm." dir)
+                                           nil suffix))))
          (let ((coding-system-for-write mm-binary-coding-system))
            (write-region (point-min) (point-max) file nil 'nomesg))
          (message "Viewing with %s" method)
@@ -785,8 +824,7 @@ external if displayed external."
                                   (mm-mailcap-command
                                    method file (mm-handle-type handle)))
                     (if (buffer-live-p buffer)
-                        (save-excursion
-                          (set-buffer buffer)
+                        (with-current-buffer buffer
                           (buffer-string))))
                 (progn
                   (ignore-errors (delete-file file))
@@ -795,14 +833,52 @@ external if displayed external."
                   (ignore-errors (kill-buffer buffer))))))
            'inline)
           (t
+           ;; Deleting the temp file should be postponed for some wrappers,
+           ;; shell scripts, and so on, which might exit right after having
+           ;; started a viewer command as a background job.
            (let ((command (mm-mailcap-command
                            method file (mm-handle-type handle))))
              (unwind-protect
-                 (start-process "*display*"
-                                (setq buffer
-                                      (generate-new-buffer " *mm*"))
-                                shell-file-name
-                                shell-command-switch command)
+                 (progn
+                   (start-process "*display*"
+                                  (setq buffer
+                                        (generate-new-buffer " *mm*"))
+                                  shell-file-name
+                                  shell-command-switch command)
+                   (set-process-sentinel
+                    (get-buffer-process buffer)
+                    (lexical-let ;; Don't use `let'.
+                        ;; Function used to remove temp file and directory.
+                        ((fn `(lambda nil
+                                ;; Don't use `ignore-errors'.
+                                (condition-case nil
+                                    (delete-file ,file)
+                                  (error))
+                                (condition-case nil
+                                    (delete-directory
+                                     ,(file-name-directory file))
+                                  (error))))
+                         ;; Form uses to kill the process buffer and
+                         ;; remove the undisplayer.
+                         (fm `(progn
+                                (kill-buffer ,buffer)
+                                ,(macroexpand
+                                  (list 'mm-handle-set-undisplayer
+                                        (list 'quote handle)
+                                        nil))))
+                         ;; Message to be issued when the process exits.
+                         (done (format "Displaying %s...done" command))
+                         ;; In particular, the timer object (which is
+                         ;; a vector in Emacs but is a list in XEmacs)
+                         ;; requires that it is lexically scoped.
+                         (timer (run-at-time 2.0 nil 'ignore)))
+                      (lambda (process state)
+                        (when (eq 'exit (process-status process))
+                          (if (memq timer timer-list)
+                              (timer-set-function timer fn)
+                            (funcall fn))
+                          (ignore-errors (eval fm))
+                          (message "%s" done))))))
                (mm-handle-set-external-undisplayer
                 handle (cons file buffer)))
              (message "Displaying %s..." command))
@@ -1001,40 +1077,54 @@ external if displayed external."
 ;;; Functions for outputting parts
 ;;;
 
-(defun mm-get-part (handle)
-  "Return the contents of HANDLE as a string."
-  (mm-with-unibyte-buffer
-    (insert (with-current-buffer (mm-handle-buffer handle)
-             (mm-with-unibyte-current-buffer
-               (buffer-string))))
-    (mm-decode-content-transfer-encoding
-     (mm-handle-encoding handle)
-     (mm-handle-media-type handle))
-    (buffer-string)))
-
-(defun mm-insert-part (handle)
-  "Insert the contents of HANDLE in the current buffer."
-  (let ((cur (current-buffer)))
-    (save-excursion
-      (if (member (mm-handle-media-supertype handle) '("text" "message"))
-         (with-temp-buffer
-           (insert-buffer-substring (mm-handle-buffer handle))
-           (prog1
-               (mm-decode-content-transfer-encoding
-                (mm-handle-encoding handle)
-                (mm-handle-media-type handle))
-             (let ((temp (current-buffer)))
-               (set-buffer cur)
-               (insert-buffer-substring temp))))
-       (mm-with-unibyte-buffer
-         (insert-buffer-substring (mm-handle-buffer handle))
-         (prog1
-             (mm-decode-content-transfer-encoding
-              (mm-handle-encoding handle)
-              (mm-handle-media-type handle))
-           (let ((temp (current-buffer)))
-             (set-buffer cur)
-             (insert-buffer-substring temp))))))))
+(defmacro mm-with-part (handle &rest forms)
+  "Run FORMS in the temp buffer containing the contents of HANDLE."
+  `(let* ((handle ,handle)
+         ;; The multibyteness of the temp buffer should be turned on
+         ;; if inserting a multibyte string.  Contrarily, the buffer's
+         ;; multibyteness should be off if inserting a unibyte string,
+         ;; especially if a string contains 8bit data.
+         (default-enable-multibyte-characters
+           (with-current-buffer (mm-handle-buffer handle)
+             (mm-multibyte-p))))
+     (with-temp-buffer
+       (insert-buffer-substring (mm-handle-buffer handle))
+       (mm-disable-multibyte)
+       (mm-decode-content-transfer-encoding
+       (mm-handle-encoding handle)
+       (mm-handle-media-type handle))
+       ,@forms)))
+(put 'mm-with-part 'lisp-indent-function 1)
+(put 'mm-with-part 'edebug-form-spec '(body))
+
+(defun mm-get-part (handle &optional no-cache)
+  "Return the contents of HANDLE as a string.
+If NO-CACHE is non-nil, cached contents of a message/external-body part
+are ignored."
+  (if (and (not no-cache)
+          (equal (mm-handle-media-type handle) "message/external-body"))
+      (progn
+       (unless (mm-handle-cache handle)
+         (mm-extern-cache-contents handle))
+       (with-current-buffer (mm-handle-buffer (mm-handle-cache handle))
+         (buffer-string)))
+    (mm-with-part handle
+      (buffer-string))))
+
+(defun mm-insert-part (handle &optional no-cache)
+  "Insert the contents of HANDLE in the current buffer.
+If NO-CACHE is non-nil, cached contents of a message/external-body part
+are ignored."
+  (save-excursion
+    (insert
+     (cond ((eq (mail-content-type-get (mm-handle-type handle) 'charset)
+               'gnus-decoded)
+           (with-current-buffer (mm-handle-buffer handle)
+             (buffer-string)))
+          ((mm-multibyte-p)
+           (mm-string-as-multibyte (mm-get-part handle no-cache)))
+          (t
+           (mm-get-part handle no-cache))))))
 
 (defun mm-file-name-delete-whitespace (file-name)
   "Remove all whitespace characters from FILE-NAME."
@@ -1074,20 +1164,22 @@ string if you do not like underscores."
   (setq filename (gnus-replace-in-string filename "[<>|]" ""))
   (gnus-replace-in-string filename "^[.-]+" ""))
 
-(defun mm-save-part (handle)
-  "Write HANDLE to a file."
-  (let* ((name (mail-content-type-get (mm-handle-type handle) 'name))
-        (filename (mail-content-type-get
-                   (mm-handle-disposition handle) 'filename))
-        file)
+(defun mm-save-part (handle &optional prompt)
+  "Write HANDLE to a file.
+PROMPT overrides the default one used to ask user for a file name."
+  (let ((filename (or (mail-content-type-get
+                      (mm-handle-disposition handle) 'filename)
+                     (mail-content-type-get
+                      (mm-handle-type handle) 'name)))
+       file)
     (when filename
       (setq filename (gnus-map-function mm-file-name-rewrite-functions
                                        (file-name-nondirectory filename))))
     (setq file
          (mm-with-multibyte
-           (read-file-name "Save MIME part to: "
-                           (or mm-default-directory default-directory)
-                           nil nil (or filename name ""))))
+          (read-file-name (or prompt "Save MIME part to: ")
+                          (or mm-default-directory default-directory)
+                          nil nil (or filename ""))))
     (setq mm-default-directory (file-name-directory file))
     (and (or (not (file-exists-p file))
             (yes-or-no-p (format "File %s already exists; overwrite? "
@@ -1241,8 +1333,8 @@ be determined."
     ;; out to a file, and then create a file
     ;; specifier.
     (let ((file (mm-make-temp-file
-                (expand-file-name "emm.xbm"
-                                  mm-tmp-directory))))
+                (expand-file-name "emm" mm-tmp-directory)
+                nil ".xbm")))
       (unwind-protect
          (progn
            (write-region (point-min) (point-max) file)
@@ -1329,9 +1421,8 @@ If RECURSIVE, search recursively."
        (save-excursion
          (save-restriction
            (narrow-to-region start (1- (point)))
-           (when (let ((ctl (ignore-errors
-                              (mail-header-parse-content-type
-                               (mail-fetch-field "content-type")))))
+           (when (let* ((ct (mail-fetch-field "content-type"))
+                        (ctl (and ct (mail-header-parse-content-type ct))))
                    (if notp
                        (not (equal (car ctl) type))
                      (equal (car ctl) type)))
@@ -1342,9 +1433,8 @@ If RECURSIVE, search recursively."
       (save-excursion
        (save-restriction
          (narrow-to-region start end)
-         (when (let ((ctl (ignore-errors
-                            (mail-header-parse-content-type
-                             (mail-fetch-field "content-type")))))
+         (when (let* ((ct (mail-fetch-field "content-type"))
+                      (ctl (and ct (mail-header-parse-content-type ct))))
                  (if notp
                      (not (equal (car ctl) type))
                    (equal (car ctl) type)))
@@ -1475,5 +1565,5 @@ If RECURSIVE, search recursively."
 
 (provide 'mm-decode)
 
-;;; arch-tag: 4f35d360-56b8-4030-9388-3ed82d359b9b
+;; arch-tag: 4f35d360-56b8-4030-9388-3ed82d359b9b
 ;;; mm-decode.el ends here