(mailcap-skip-comment): Check `chr' is nil.
[elisp/semi.git] / mime-edit.el
index 3ec9818..90dcc5a 100644 (file)
@@ -7,7 +7,7 @@
 ;; Maintainer: MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;; Created: 1994/08/21 renamed from mime.el
 ;;     Renamed: 1997/2/21 from tm-edit.el
-;; Version: $Revision: 0.66 $
+;; Version: $Revision: 0.88 $
 ;; Keywords: MIME, multimedia, multilingual, mail, news
 
 ;; This file is part of SEMI (SEMI is Emacs MIME Interfaces).
 ;; News mode.  First of all, you need the following autoload
 ;; definition to load mime-edit-mode automatically:
 ;;
-;; (autoload 'mime-edit-mode "mime-edit"
+;; (autoload 'turn-on-mime-edit "mime-edit"
 ;;           "Minor mode for editing MIME message." t)
 ;;
 ;; In case of Mail mode (includes VM mode), you need the following
 ;; hook definition:
 ;;
-;; (add-hook 'mail-mode-hook 'mime-edit-mode)
+;; (add-hook 'mail-mode-hook 'turn-on-mime-edit)
 ;; (add-hook 'mail-send-hook 'mime-edit-maybe-translate)
 ;;
 ;; In case of MH-E, you need the following hook definition:
@@ -63,7 +63,7 @@
 ;; (add-hook 'mh-letter-mode-hook
 ;;           (function
 ;;            (lambda ()
-;;              (mime-edit-mode)
+;;              (turn-on-mime-edit)
 ;;              (make-local-variable 'mail-header-separator)
 ;;              (setq mail-header-separator "--------")
 ;;              ))))
@@ -71,7 +71,7 @@
 ;;
 ;; In case of News mode, you need the following hook definition:
 ;;
-;; (add-hook 'news-reply-mode-hook 'mime-edit-mode)
+;; (add-hook 'news-reply-mode-hook 'turn-on-mime-edit)
 ;; (add-hook 'news-inews-hook 'mime-edit-maybe-translate)
 ;;
 ;; In case of Emacs 19, it is possible to emphasize the message tags
 ;;;
 
 (defconst mime-edit-RCS-ID
-  "$Id: mime-edit.el,v 0.66 1997-03-06 20:46:31 morioka Exp $")
+  "$Id: mime-edit.el,v 0.88 1997-09-05 07:10:59 morioka Exp $")
 
-(defconst mime-edit-version (get-version-string mime-edit-RCS-ID))
+(defconst mime-edit-version `,(get-version-string mime-edit-RCS-ID))
 
 (defconst mime-edit-version-name
-  (concat "SEMI MIME-Edit " mime-edit-version))
+  `,(concat "SEMI MIME-Edit " mime-edit-version
+           " \"" semi-version-name "\""))
 
 
 ;;; @ variables
@@ -148,7 +149,7 @@ If non-nil, the text tag is not inserted unless something different.")
 
 (defvar mime-edit-voice-recorder
   (function mime-edit-voice-recorder-for-sun)
-  "*Function to record a voice message and encode it. [mime-edit.el]")
+  "*Function to record a voice message and encode it.")
 
 (defvar mime-edit-mode-hook nil
   "*Hook called when enter MIME mode.")
@@ -180,7 +181,7 @@ To insert a signature file automatically, call the function
      ("html"
       ;;("charset" "" "ISO-2022-JP" "US-ASCII" "ISO-8859-1" "ISO-8859-8")
       )
-     ("x-rot13-47")
+     ("x-rot13-47-48")
      )
     ("message"
      ("external-body"
@@ -209,6 +210,7 @@ To insert a signature file automatically, call the function
     ("image"
      ("gif")
      ("jpeg")
+     ("png")
      ("tiff")
      ("x-pic")
      ("x-mag")
@@ -244,6 +246,11 @@ To insert a signature file automatically, call the function
      "base64"
      "inline"          (("filename" . file))
      )
+    ("\\.png$"
+     "image"   "png"           nil
+     "base64"
+     "inline"          (("filename" . file))
+     )
     ("\\.tiff$"
      "image"   "tiff"          nil
      "base64"
@@ -417,7 +424,7 @@ If encoding is nil, it is determined from its contents.")
     "Xref" "X-UIDL" "X-Filter" "X-Gnus-.*" "X-VM-.*")
   "Delete these fields from original message when it is inserted
 as message/rfc822 part.
-Each elements are regexp of field-name. [mime-edit.el]")
+Each elements are regexp of field-name.")
 
 (defvar mime-edit-yank-ignored-field-regexp
   (concat "^"
@@ -432,16 +439,16 @@ Each elements are regexp of field-name. [mime-edit.el]")
 ;;;
 
 (defvar mime-edit-split-message t
-  "*Split large message if it is non-nil. [mime-edit.el]")
+  "*Split large message if it is non-nil.")
 
 (defvar mime-edit-message-default-max-lines 1000
-  "*Default maximum lines of a message. [mime-edit.el]")
+  "*Default maximum lines of a message.")
 
 (defvar mime-edit-message-max-lines-alist
   '((news-reply-mode . 500))
   "Alist of major-mode vs maximum lines of a message.
 If it is not specified for a major-mode,
-`mime-edit-message-default-max-lines' is used. [mime-edit.el]")
+`mime-edit-message-default-max-lines' is used.")
 
 (defconst mime-edit-split-ignored-field-regexp
   "\\(^Content-\\|^Subject:\\|^Mime-Version:\\)")
@@ -458,10 +465,10 @@ If it is not specified for a major-mode,
 ;;;
 
 (defvar mime-edit-signing-type 'pgp-elkins
-  "*PGP signing type (pgp-elkins, pgp-kazu or nil). [mime-edit.el]")
+  "*PGP signing type (pgp-elkins, pgp-kazu or nil).")
 
 (defvar mime-edit-encrypting-type 'pgp-elkins
-  "*PGP encrypting type (pgp-elkins, pgp-kazu or nil). [mime-edit.el]")
+  "*PGP encrypting type (pgp-elkins, pgp-kazu or nil).")
 
 
 ;;; @@ about tag
@@ -543,37 +550,65 @@ Tspecials means any character that matches with it in header must be quoted.")
 (defvar mime-edit-mode-flag nil)
 (make-variable-buffer-local 'mime-edit-mode-flag)
 
-(defvar mime-edit-prefix "\C-c\C-x"
-  "*Keymap prefix for MIME-Edit commands.")
-
-(defvar mime-edit-map (make-sparse-keymap)
-  "Keymap for MIME commands.")
-
-(define-key mime-edit-map "\C-t"       'mime-edit-insert-text)
-(define-key mime-edit-map "\C-i"       'mime-edit-insert-file)
-(define-key mime-edit-map "\C-e"       'mime-edit-insert-external)
-(define-key mime-edit-map "\C-v"       'mime-edit-insert-voice)
-(define-key mime-edit-map "\C-y"       'mime-edit-insert-message)
-(define-key mime-edit-map "\C-m"       'mime-edit-insert-mail)
-(define-key mime-edit-map "\C-w"       'mime-edit-insert-signature)
-(define-key mime-edit-map "\C-s"       'mime-edit-insert-signature)
-(define-key mime-edit-map "\C-k"       'mime-edit-insert-key)
-(define-key mime-edit-map "t"          'mime-edit-insert-tag)
-(define-key mime-edit-map "a"          'mime-edit-enclose-alternative-region)
-(define-key mime-edit-map "p"          'mime-edit-enclose-parallel-region)
-(define-key mime-edit-map "m"          'mime-edit-enclose-mixed-region)
-(define-key mime-edit-map "d"          'mime-edit-enclose-digest-region)
-(define-key mime-edit-map "s"          'mime-edit-enclose-signed-region)
-(define-key mime-edit-map "e"          'mime-edit-enclose-encrypted-region)
-(define-key mime-edit-map "q"          'mime-edit-enclose-quote-region)
-(define-key mime-edit-map "7"          'mime-edit-set-transfer-level-7bit)
-(define-key mime-edit-map "8"          'mime-edit-set-transfer-level-8bit)
-(define-key mime-edit-map "/"          'mime-edit-set-split)
-(define-key mime-edit-map "v"          'mime-edit-set-sign)
-(define-key mime-edit-map "h"          'mime-edit-set-encrypt)
-(define-key mime-edit-map "\C-p"       'mime-edit-preview-message)
-(define-key mime-edit-map "\C-z"       'mime-edit-exit)
-(define-key mime-edit-map "?"          'mime-edit-help)
+(defvar mime-edit-mode-map (make-sparse-keymap)
+  "Keymap for MIME-Edit mode commands.")
+
+(define-key mime-edit-mode-map
+  "\C-c\C-x\C-t"       'mime-edit-insert-text)
+(define-key mime-edit-mode-map
+  "\C-c\C-x\C-i"       'mime-edit-insert-file)
+(define-key mime-edit-mode-map
+  "\C-c\C-x\C-e"       'mime-edit-insert-external)
+(define-key mime-edit-mode-map
+  "\C-c\C-x\C-v"       'mime-edit-insert-voice)
+(define-key mime-edit-mode-map
+  "\C-c\C-x\C-y"       'mime-edit-insert-message)
+(define-key mime-edit-mode-map
+  "\C-c\C-x\C-m"       'mime-edit-insert-mail)
+(define-key mime-edit-mode-map
+  "\C-c\C-x\C-w"       'mime-edit-insert-signature)
+(define-key mime-edit-mode-map
+  "\C-c\C-x\C-s"       'mime-edit-insert-signature)
+(define-key mime-edit-mode-map
+  "\C-c\C-x\C-k"       'mime-edit-insert-key)
+(define-key mime-edit-mode-map
+  "\C-c\C-xt"          'mime-edit-insert-tag)
+
+(define-key mime-edit-mode-map
+  "\C-c\C-m\C-a"       'mime-edit-enclose-alternative-region)
+(define-key mime-edit-mode-map
+  "\C-c\C-m\C-p"       'mime-edit-enclose-parallel-region)
+(define-key mime-edit-mode-map
+  "\C-c\C-m\C-m"       'mime-edit-enclose-mixed-region)
+(define-key mime-edit-mode-map
+  "\C-c\C-m\C-d"       'mime-edit-enclose-digest-region)
+(define-key mime-edit-mode-map
+  "\C-c\C-m\C-s"       'mime-edit-enclose-signed-region)
+(define-key mime-edit-mode-map
+  "\C-c\C-m\C-e"       'mime-edit-enclose-encrypted-region)
+(define-key mime-edit-mode-map
+  "\C-c\C-m\C-q"       'mime-edit-enclose-quote-region)
+
+(define-key mime-edit-mode-map
+  "\C-c\C-x7"          'mime-edit-set-transfer-level-7bit)
+(define-key mime-edit-mode-map
+  "\C-c\C-x8"          'mime-edit-set-transfer-level-8bit)
+(define-key mime-edit-mode-map
+  "\C-c\C-x/"          'mime-edit-set-split)
+(define-key mime-edit-mode-map
+  "\C-c\C-xs"          'mime-edit-set-sign)
+(define-key mime-edit-mode-map
+  "\C-c\C-xv"          'mime-edit-set-sign)
+(define-key mime-edit-mode-map
+  "\C-c\C-xe"          'mime-edit-set-encrypt)
+(define-key mime-edit-mode-map
+  "\C-c\C-xh"          'mime-edit-set-encrypt)
+(define-key mime-edit-mode-map
+  "\C-c\C-x\C-p"       'mime-edit-preview-message)
+(define-key mime-edit-mode-map
+  "\C-c\C-x\C-z"       'mime-edit-exit)
+(define-key mime-edit-mode-map
+  "\C-c\C-x?"          'mime-edit-help)
 
 (defconst mime-edit-menu-title "MIME-Edit")
 
@@ -604,10 +639,6 @@ Tspecials means any character that matches with it in header must be quoted.")
     )
   "MIME-edit menubar entry.")
 
-(defvar mime-edit-mode-map (make-sparse-keymap)
-  "Keymap for MIME-Edit mode commands.")
-(define-key mime-edit-mode-map mime-edit-prefix mime-edit-map)
-
 (cond (running-xemacs
        ;; modified by Pekka Marjola <pema@iki.fi>
        ;;      1995/9/5 (c.f. [tm-en:69])
@@ -654,29 +685,6 @@ Tspecials means any character that matches with it in header must be quoted.")
               )
        ))
 
-(defun mime-edit-toggle-mode ()
-  (interactive)
-  (if mime-edit-mode-flag
-      (mime-edit-exit 'nomime)
-    (mime-edit-mode)
-    ))
-
-(cond (running-xemacs
-       (add-minor-mode 'mime-edit-mode-flag
-                      '((" MIME-Edit "  mime-transfer-level-string))
-                      mime-edit-mode-map
-                      nil
-                      'mime-edit-toggle-mode)
-       )
-      (t
-       (set-alist 'minor-mode-alist
-                 'mime-edit-mode-flag
-                 '((" MIME-Edit "  mime-transfer-level-string)))
-       (set-alist 'minor-mode-map-alist
-                 'mime-edit-mode-flag
-                 mime-edit-mode-map)
-       ))
-
 
 ;;; @ functions
 ;;;
@@ -815,6 +823,38 @@ User customizable variables (not documented all of them):
     non-nil."
   (interactive)
   (if mime-edit-mode-flag
+      (mime-edit-exit)
+    (if (and (boundp 'mime-edit-touched-flag)
+            mime-edit-touched-flag)
+       (mime-edit-again)
+      (make-local-variable 'mime-edit-touched-flag)
+      (setq mime-edit-touched-flag t)
+      (turn-on-mime-edit)
+      )))
+
+
+(cond (running-xemacs
+       (add-minor-mode 'mime-edit-mode-flag
+                      '((" MIME-Edit "  mime-transfer-level-string))
+                      mime-edit-mode-map
+                      nil
+                      'mime-edit-mode)
+       )
+      (t
+       (set-alist 'minor-mode-alist
+                 'mime-edit-mode-flag
+                 '((" MIME-Edit "  mime-transfer-level-string)))
+       (set-alist 'minor-mode-map-alist
+                 'mime-edit-mode-flag
+                 mime-edit-mode-map)
+       ))
+
+
+;;;###autoload
+(defun turn-on-mime-edit ()
+  "Unconditionally turn on MIME-Edit mode."
+  (interactive)
+  (if mime-edit-mode-flag
       (error "You are already editing a MIME message.")
     (setq mime-edit-mode-flag t)
     
@@ -824,15 +864,10 @@ User customizable variables (not documented all of them):
          (mime-encoding-name mime-transfer-level 'not-omit))
     (force-mode-line-update)
     
-    ;; Define menu.  Menus for other emacs implementations are
-    ;; welcome.
-    (cond (running-xemacs
-          (mime-edit-define-menu-for-xemacs))
-          ;; ((>= emacs-major-version 19)
-          ;;  (mime-edit-define-menu-for-emacs19)
-          ;;  )
-         )
-    ;; end
+    ;; Define menu for XEmacs.
+    (if running-xemacs
+       (mime-edit-define-menu-for-xemacs)
+      )
     
     (enable-invisible)
     
@@ -850,8 +885,8 @@ User customizable variables (not documented all of them):
     ))
 
 ;;;###autoload
-(defalias 'edit-mime 'mime-edit-mode)          ; for convenience
-(defalias 'mime-mode 'mime-edit-mode)          ; for convenience
+(defalias 'edit-mime 'turn-on-mime-edit) ; for convenience
+
 
 (defun mime-edit-exit (&optional nomime no-error)
   "Translate the tagged MIME message into a MIME compliant message.
@@ -1120,7 +1155,7 @@ Optional argument ENCODING specifies an encoding method such as base64."
 
 (defun mime-edit-goto-tag ()
   "Search for the beginning of the tagged MIME message."
-  (let ((current (point)) multipart)
+  (let ((current (point)))
     (if (looking-at mime-edit-tag-regexp)
        t
       ;; At first, go to the end.
@@ -1165,26 +1200,25 @@ Optional argument ENCODING specifies an encoding method such as base64."
 (defun mime-edit-content-end ()
   "Return the point of the end of content."
   (save-excursion
-    (let ((beg (point)))
-      (if (mime-edit-goto-tag)
-         (let ((top (point)))
-           (goto-char (match-end 0))
-           (if (invisible-p (point))
-               (next-visible-point (point))
-             ;; Move to the end of this text.
-             (if (re-search-forward mime-edit-tag-regexp nil 'move)
-                 ;; Don't forget a multiline tag.
-                 (goto-char (match-beginning 0))
-               )
-             (point)
-             ))
-       ;; Assume the message begins with text/plain.
-       (goto-char (mime-edit-content-beginning))
-       (if (re-search-forward mime-edit-tag-regexp nil 'move)
-           ;; Don't forget a multiline tag.
-           (goto-char (match-beginning 0)))
-       (point))
-      )))
+    (if (mime-edit-goto-tag)
+       (progn
+         (goto-char (match-end 0))
+         (if (invisible-p (point))
+             (next-visible-point (point))
+           ;; Move to the end of this text.
+           (if (re-search-forward mime-edit-tag-regexp nil 'move)
+               ;; Don't forget a multiline tag.
+               (goto-char (match-beginning 0))
+             )
+           (point)
+           ))
+      ;; Assume the message begins with text/plain.
+      (goto-char (mime-edit-content-beginning))
+      (if (re-search-forward mime-edit-tag-regexp nil 'move)
+         ;; Don't forget a multiline tag.
+         (goto-char (match-beginning 0)))
+      (point))
+    ))
 
 (defun mime-edit-define-charset (charset)
   "Set charset of current tag to CHARSET."
@@ -1416,7 +1450,7 @@ Parameter must be '(PROMPT CHOICE1 (CHOISE2 ...))."
     ))
 
 (defun mime-prompt-for-encoding (default)
-  "Ask for Content-Transfer-Encoding. [mime-edit.el]"
+  "Ask for Content-Transfer-Encoding."
   (let (encoding)
     (while (string=
            (setq encoding
@@ -1572,8 +1606,9 @@ Parameter must be '(PROMPT CHOICE1 (CHOISE2 ...))."
            (insert (format "Content-Transfer-Encoding: %s\n" encoding))
          )
        (insert "\n")
-       (or (funcall (pgp-function 'mime-sign)
-                    (point-min)(point-max) nil nil pgp-boundary)
+       (or (as-binary-process
+            (funcall (pgp-function 'mime-sign)
+                     (point-min)(point-max) nil nil pgp-boundary))
            (throw 'mime-edit-error 'pgp-error)
            )
        ))))
@@ -1794,22 +1829,24 @@ Content-Transfer-Encoding: 7bit
        ))))
 
 (defun mime-edit-translate-single-part-tag (&optional prefix)
+  "Translate single-part-tag to MIME header."
   (if (re-search-forward mime-edit-single-part-tag-regexp nil t)
       (let* ((beg (match-beginning 0))
             (end (match-end 0))
             (tag (buffer-substring beg end))
             )
        (delete-region beg end)
-       (setq contype (mime-edit-get-contype tag))
-       (setq encoding (mime-edit-get-encoding tag))
-       (insert (concat prefix "--" boundary "\n"))
-       (save-restriction
-         (narrow-to-region (point)(point))
-         (insert "Content-Type: " contype "\n")
-         (if encoding
-             (insert "Content-Transfer-Encoding: " encoding "\n"))
-         (eword-encode-header)
-         )
+       (let ((contype (mime-edit-get-contype tag))
+             (encoding (mime-edit-get-encoding tag))
+             )
+         (insert (concat prefix "--" boundary "\n"))
+         (save-restriction
+           (narrow-to-region (point)(point))
+           (insert "Content-Type: " contype "\n")
+           (if encoding
+               (insert "Content-Transfer-Encoding: " encoding "\n"))
+           (eword-encode-header)
+           ))
        t)))
 
 (defun mime-edit-translate-region (beg end &optional boundary multipart)
@@ -1904,12 +1941,10 @@ Content-Transfer-Encoding: 7bit
                          (intern (downcase charset))
                        (mime-edit-choose-charset)))
        (mime-edit-define-charset charset)
-       (cond ((string-equal contype "text/x-rot13-47")
+       (cond ((string-equal contype "text/x-rot13-47-48")
               (save-excursion
                 (forward-line)
-                (set-mark (point))
-                (goto-char (mime-edit-content-end))
-                (tm:caesar-region)
+                (mule-caesar-region (point) (mime-edit-content-end))
                 ))
              ((string-equal contype "text/enriched")
               (save-excursion
@@ -1944,6 +1979,33 @@ Content-Transfer-Encoding: 7bit
                   )
              (encode-mime-charset-region beg (mime-edit-content-end)
                                          charset)
+             ;; Protect "From " in beginning of line
+             (save-restriction
+               (narrow-to-region beg (mime-edit-content-end))
+               (goto-char beg)
+               (if (re-search-forward "^From " nil t)
+                   (unless encoding
+                     (if (memq charset '(iso-2022-jp
+                                         iso-2022-jp-2
+                                         iso-2022-int-1
+                                         x-ctext))
+                         (while (progn
+                                  (replace-match "\e(BFrom ")
+                                  (re-search-forward "^From " nil t)
+                                  ))
+                       (setq encoding "quoted-printable")
+                       ))))
+             ;; canonicalize line break code
+             (or (member encoding '(nil "7bit" "8bit" "quoted-printable"))
+                 (save-restriction
+                   (narrow-to-region beg (mime-edit-content-end))
+                   (goto-char beg)
+                   (while (re-search-forward "\\([^\r]\\)\n" nil t)
+                     (replace-match
+                      (concat (buffer-substring (match-beginning 0)
+                                                (match-end 1)) "\r\n"))
+                     )))
+             (goto-char beg)
              (mime-encode-region beg (mime-edit-content-end) encoding)
              (mime-edit-define-encoding encoding)
              ))
@@ -1982,7 +2044,7 @@ Content-Transfer-Encoding: 7bit
 
 (defun mime-edit-voice-recorder-for-sun (encoding)
   "Record voice in a buffer using Sun audio device,
-and insert data encoded as ENCODING. [mime-edit.el]"
+and insert data encoded as ENCODING."
   (message "Start the recording on %s.  Type C-g to finish the recording..."
           (system-name))
   (mime-insert-encoded-file "/dev/audio" encoding)
@@ -2347,7 +2409,7 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
 (defvar mime-edit-buffer nil) ; buffer local variable
 
 (defun mime-edit-preview-message ()
-  "preview editing MIME message. [mime-edit.el]"
+  "preview editing MIME message."
   (interactive)
   (let* ((str (buffer-string))
         (separator mail-header-separator)
@@ -2382,7 +2444,8 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
     ))
 
 (defun mime-edit-quitting-method ()
-  (let ((temp mime::preview/article-buffer)
+  "Quitting method for mime-view."
+  (let ((temp mime-raw-buffer)
        buf)
     (mime-view-kill-buffer)
     (set-buffer temp)
@@ -2400,26 +2463,26 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
 ;;; @ edit again
 ;;;
 
-(defun mime-editor::edit-again (code-conversion)
+(defvar mime-edit-again-ignored-field-regexp
+  (concat "^\\(" "Content-.*\\|Mime-Version"
+         (if mime-edit-insert-x-emacs-field "\\|X-Emacs")
+         "\\):")
+  "Regexp for deleted header fields when `mime-edit-again' is called.")
+
+(defun mime-edit-decode-buffer (not-decode-text)
   (save-excursion
     (goto-char (point-min))
-    (let ((ctl (mime/Content-Type)))
+    (let ((ctl (mime-read-Content-Type)))
       (if ctl
-         (let ((ctype (car ctl))
-               (params (cdr ctl))
-               type stype)
-           (if (string-match "/" ctype)
-               (progn
-                 (setq type (substring ctype 0 (match-beginning 0)))
-                 (setq stype (substring ctype (match-end 0)))
-                 )
-             (setq type ctype)
-             )
+         (let ((type (car ctl))
+               (stype (car (cdr ctl)))
+               (params (cdr (cdr ctl)))
+               )
            (cond
-            ((string= ctype "application/pgp-signature")
+            ((and (eq type 'application)(eq stype 'pgp-signature))
              (delete-region (point-min)(point-max))
              )
-            ((string= type "multipart")
+            ((eq type 'multipart)
              (let* ((boundary (cdr (assoc "boundary" params)))
                     (boundary-pat
                      (concat "\n--" (regexp-quote boundary) "[ \t]*\n"))
@@ -2449,7 +2512,7 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
                            )
                          (save-restriction
                            (narrow-to-region beg end)
-                           (mime-editor::edit-again code-conversion)
+                           (mime-edit-decode-buffer not-decode-text)
                            (goto-char (point-max))
                            ))))
                    ))
@@ -2462,12 +2525,13 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
                                     )))
                ))
             (t
-             (let* (charset
+             (let* ((ctype (format "%s/%s" type stype))
+                    charset
                     (pstr
                      (let ((bytes (+ 14 (length ctype))))
                        (mapconcat (function
                                    (lambda (attr)
-                                     (if (string-equal (car attr) "charset")
+                                     (if (string= (car attr) "charset")
                                          (progn
                                            (setq charset (cdr attr))
                                            "")
@@ -2497,7 +2561,7 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
                              (eliminate-top-spaces
                               (std11-unfold-string
                                (buffer-substring hbeg end))))
-                       (if (or charset (string-equal type "text"))
+                       (if (or charset (eq type 'text))
                            (progn
                              (delete-region beg (1+ end))
                              (goto-char (point-min))
@@ -2508,7 +2572,7 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
                                    (setq encoded t
                                          encoding nil)
                                    )))))))
-               (if (or code-conversion encoded)
+               (if (or encoded (not not-decode-text))
                    (decode-mime-charset-region
                     (point-min)(point-max)
                     (or charset default-mime-charset))
@@ -2524,47 +2588,47 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
                        (insert
                         (concat "\n"
                                 (mime-create-tag
-                                 (concat type "/" stype pstr) encoding)))
+                                 (format "%s/%s%s" type stype pstr)
+                                 encoding)))
                        )
                    (delete-region (point-min) he)
                    (insert
                     (mime-create-tag
-                     (concat type "/" stype pstr) encoding))
+                     (format "%s/%s%s" type stype pstr)
+                     encoding))
                    ))
                ))))
-       (if code-conversion
+       (or not-decode-text
            (decode-mime-charset-region (point-min) (point-max)
                                        default-mime-charset)
-         )
+           )
        ))))
 
-(defun mime-edit-again (&optional code-conversion no-separator no-mode)
+(defun mime-edit-again (&optional not-decode-text no-separator not-turn-on)
   "Convert current buffer to MIME-Edit buffer and turn on MIME-Edit mode.
 Content-Type and Content-Transfer-Encoding header fields will be
 converted to MIME-Edit tags."
   (interactive)
-  (mime-editor::edit-again code-conversion)
+  (goto-char (point-min))
+  (if (search-forward
+       (concat "\n" (regexp-quote mail-header-separator) "\n")
+       nil t)
+      (replace-match "\n\n")
+    )
+  (mime-edit-decode-buffer not-decode-text)
   (goto-char (point-min))
   (save-restriction
-    (narrow-to-region
-     (point-min)
-     (if (re-search-forward
-         (concat "^\\(" (regexp-quote mail-header-separator) "\\)?$")
-         nil t)
-        (match-end 0)
-       (point-max)
-       ))
+    (std11-narrow-to-header)
     (goto-char (point-min))
-    (while (re-search-forward
-           "^\\(Content-.*\\|Mime-Version\\):" nil t)
+    (while (re-search-forward mime-edit-again-ignored-field-regexp nil t)
       (delete-region (match-beginning 0) (1+ (std11-field-end)))
       ))
   (or no-separator
       (and (re-search-forward "^$")
           (replace-match mail-header-separator)
           ))
-  (or no-mode
-      (mime-edit-mode)
+  (or not-turn-on
+      (turn-on-mime-edit)
       ))