tm 7.70.
[elisp/tm.git] / tm-edit.el
index fcfbf70..8e7334f 100644 (file)
@@ -2,13 +2,13 @@
 ;;; tm-edit.el --- Simple MIME Composer for GNU Emacs
 ;;;
 ;;; Copyright (C) 1993 UMEDA Masanobu
-;;; Copyright (C) 1994,1995 MORIOKA Tomohiko
+;;; Copyright (C) 1994 .. 1996 MORIOKA Tomohiko
 ;;;
 ;;; Author: UMEDA Masanobu <umerin@mse.kyutech.ac.jp>
 ;;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;;; Maintainer: MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;;; Created: 1994/08/21 renamed from mime.el
-;;; Version: $Revision: 7.41 $
+;;; Version: $Revision: 7.70 $
 ;;; Keywords: mail, news, MIME, multimedia, multilingual
 ;;;
 ;;; This file is part of tm (Tools for MIME).
 ;;;
 
 (defconst mime-editor/RCS-ID
-  "$Id: tm-edit.el,v 7.41 1996/01/18 17:49:17 morioka Exp $")
+  "$Id: tm-edit.el,v 7.70 1996/07/09 13:30:32 morioka Exp $")
 
 (defconst mime-editor/version (get-version-string mime-editor/RCS-ID))
 
 (defvar mime-prefix "\C-c\C-x"
   "*Keymap prefix for MIME commands.")
 
-(defvar mime-signature-file "~/.signature.rtf"
-  "*Signature file to be included as a part of a multipart message.")
-
 (defvar mime-ignore-preceding-spaces nil
   "*Ignore preceding white spaces if non-nil.")
 
@@ -149,18 +146,6 @@ If non-nil, the text tag is not inserted unless something different.")
 (defvar mime-auto-hide-body t
   "*Hide non-textual body encoded in base64 after insertion if non-nil.")
 
-(defvar mime-string-encoder
-  (cond ((boundp 'NEMACS)
-        (function mime-string-encoder-for-nemacs))
-       ((featurep 'mule)
-        (function mime-string-encoder-for-mule))
-       ((string-match "^19\\." emacs-version)
-        (function mime-string-encoder-for-emacs19))
-       (t                              ;ASCII only emacs
-        (function mime-string-encoder-for-emacs18)))
-  "*Function to encode a string for given encoding method.
-The method is a form of (CHARSET . ENCODING).")
-
 (defvar mime-voice-recorder
   (function mime-voice-recorder-for-sun)
   "*Function to record a voice message and return a buffer that contains it.")
@@ -170,8 +155,7 @@ The method is a form of (CHARSET . ENCODING).")
 
 (defvar mime-editor/translate-hook nil
   "*Hook called before translating into a MIME compliant message.
-To insert a signature file specified by mime-signature-file
-(`.signature.rtf' by default) automatically, call the function
+To insert a signature file automatically, call the function
 `mime-editor/insert-signature' from this hook.")
 
 (defvar mime-editor/exit-hook nil
@@ -350,6 +334,11 @@ To insert a signature file specified by mime-signature-file
      nil
      "attachment"      (("filename" . file))
      )
+    ("\\.patch$"
+     "application" "octet-stream" (("type" . "patch"))
+     nil
+     "attachment"      (("filename" . file))
+     )
     ("\\.signature"
      "text"    "plain"         nil     nil)
     (".*"
@@ -361,11 +350,27 @@ To insert a signature file specified by mime-signature-file
   "*Alist of file name, types, parameters, and default encoding.
 If encoding is nil, it is determined from its contents.")
 
+;;; @@ about charset, encoding and transfer-level
+;;;
+
+(defvar mime-editor/transfer-level 7
+  "*A number of network transfer level. It should be bigger than 7.")
+(make-variable-buffer-local 'mime-editor/transfer-level)
+
+(defvar mime-editor/transfer-level-string
+  (mime/encoding-name mime-editor/transfer-level 'not-omit)
+  "*A string formatted version of mime/defaul-transfer-level")
+(make-variable-buffer-local 'mime-editor/transfer-level-string)
+
+(defvar mime-editor/charset-default-encoding-alist
+  (mime/make-charset-default-encoding-alist mime-editor/transfer-level))
+(make-variable-buffer-local 'mime-editor/charset-default-encoding-alist)
+
 ;;; @@ about message inserting
 ;;;
 
 (defvar mime-editor/yank-ignored-field-list
-  '("Received" "Sender" "Approved" "Path" "Status" "X-VM-.*" "X-UIDL")
+  '("Received" "Approved" "Path" "Replied" "Status" "X-VM-.*" "X-UIDL")
   "Delete these fields from original message when it is inserted
 as message/rfc822 part.
 Each elements are regexp of field-name. [tm-edit.el]")
@@ -396,19 +401,8 @@ Each elements are regexp of field-name. [tm-edit.el]")
 (defvar mime-editor/split-blind-field-regexp
   "\\(^[BDFbdf]cc:\\|^cc:[ \t]*$\\)")
 
-(defvar mime-editor/message-default-sender-alist
-  '((mail-mode . mail-send-and-exit)
-    (mh-letter-mode . mh-send-letter)
-    (news-reply-mode . gnus-inews-news)
-    ))
-
 (defvar mime-editor/split-message-sender-alist
-  '((mail-mode
-     . (lambda ()
-        (interactive)
-        (sendmail-send-it)
-        ))
-    (mh-letter-mode
+  '((mh-letter-mode
      . (lambda (&optional arg)
         (interactive "P")
         (write-region (point-min) (point-max)
@@ -431,22 +425,6 @@ Each elements are regexp of field-name. [tm-edit.el]")
         ))
     ))
 
-(defvar mime-editor/window-config-alist
-  '((mail-mode       . nil)
-    (mh-letter-mode  . mh-previous-window-config)
-    (news-reply-mode . (cond ((boundp 'gnus-winconf-post-news)
-                             (prog1
-                                 gnus-winconf-post-news
-                               (setq gnus-winconf-post-news nil)
-                               ))
-                            ((boundp 'gnus-prev-winconf)
-                             (prog1
-                                 gnus-prev-winconf
-                               (setq gnus-prev-winconf nil)
-                               ))
-                            ))
-    ))
-
 (defvar mime-editor/news-reply-mode-server-running nil)
 
 
@@ -520,6 +498,11 @@ Tspecials means any character that matches with it in header must be quoted.")
   (format "1.0 (generated by tm-edit %s)" mime-editor/version)
   "MIME version number.")
 
+(defconst mime-editor/mime-map (make-sparse-keymap)
+  "Keymap for MIME commands.")
+
+(defconst mime-editor/minor-mime-map nil
+  "Keymap for MIME commands.")
 
 ;;; @ keymap and menu
 ;;;
@@ -527,8 +510,6 @@ Tspecials means any character that matches with it in header must be quoted.")
 (defvar mime/editor-mode-flag nil)
 (make-variable-buffer-local 'mime/editor-mode-flag)
 
-(set-alist 'minor-mode-alist 'mime/editor-mode-flag '(" MIME-Edit"))
-
 (defun mime-editor/define-keymap (keymap)
   "Add mime-editor commands to KEYMAP."
   (if (not (keymapp keymap))
@@ -554,36 +535,57 @@ Tspecials means any character that matches with it in header must be quoted.")
     (define-key keymap "?"    'mime-editor/help)
     ))
 
+(mime-editor/define-keymap mime-editor/mime-map)
+
+(if mime-editor/minor-mime-map
+    ()
+  (setq mime-editor/minor-mime-map 
+       (make-sparse-keymap 'mime-editor/minor-mime-map))
+  (define-key mime-editor/minor-mime-map mime-prefix mime-editor/mime-map))
+
+(defun mime-editor/toggle-mode ()
+  (interactive)
+  (if mime/editor-mode-flag
+      (mime-editor/exit 'nomime)
+    (mime/editor-mode)
+    ))
+
+(if running-xemacs
+    (add-minor-mode 'mime/editor-mode-flag
+                   '((" MIME-Edit "  mime-editor/transfer-level-string))
+                   mime-editor/minor-mime-map
+                   nil
+                   'mime-editor/toggle-mode)
+  (set-alist 'minor-mode-alist
+            'mime/editor-mode-flag
+            '((" MIME-Edit "  mime-editor/transfer-level-string))))
+
 (defconst mime-editor/menu-title "MIME-Edit")
 
 (defconst mime-editor/menu-list
-  (nconc
-   '((mime-help        "Describe MIME editor mode" mime-editor/help)
-     (file     "Insert File"           mime-editor/insert-file)
-     (external "Insert External"       mime-editor/insert-external)
-     (voice    "Insert Voice"          mime-editor/insert-voice)
-     (message  "Insert Message"        mime-editor/insert-message)
-     (mail     "Insert Mail"           mime-editor/insert-mail)
-     (signature        "Insert Signature"      mime-editor/insert-signature)
-     (text     "Insert Text"           mime-editor/insert-text)
-     (tag      "Insert Tag"            mime-editor/insert-tag)
-     (alternative "Enclose as alternative"
-                 mime-editor/enclose-alternative-region)
-     (parallel "Enclose as parallel"   mime-editor/enclose-parallel-region)
-     (mixed    "Enclose as serial"     mime-editor/enclose-mixed-region)
-     (digest   "Enclose as digest"     mime-editor/enclose-digest-region)
-     (signed   "Enclose as signed"     mime-editor/enclose-signed-region)
-     (encrypted        "Enclose as encrypted"  mime-editor/enclose-encrypted-region)
-     (key      "Insert Public Key"     mime-editor/insert-key)
-     (split     "About split"           mime-editor/set-split)
-     )
-   (if (and (featurep 'mailcrypt)
-           (not (or mime-editor/signing-type mime-editor/encrypting-type)))
-       '((sign    "About sign"       mime-editor/set-sign)
-        (encrypt "About encryption" mime-editor/set-encrypt)
-        ))
-   '((preview  "Preview Message"       mime-editor/preview-message))
-   )
+  '((mime-help "Describe MIME editor mode" mime-editor/help)
+    (file      "Insert File"           mime-editor/insert-file)
+    (external  "Insert External"       mime-editor/insert-external)
+    (voice     "Insert Voice"          mime-editor/insert-voice)
+    (message   "Insert Message"        mime-editor/insert-message)
+    (mail      "Insert Mail"           mime-editor/insert-mail)
+    (signature "Insert Signature"      mime-editor/insert-signature)
+    (text      "Insert Text"           mime-editor/insert-text)
+    (tag       "Insert Tag"            mime-editor/insert-tag)
+    (alternative "Enclose as alternative"
+                mime-editor/enclose-alternative-region)
+    (parallel  "Enclose as parallel"   mime-editor/enclose-parallel-region)
+    (mixed     "Enclose as serial"     mime-editor/enclose-mixed-region)
+    (digest    "Enclose as digest"     mime-editor/enclose-digest-region)
+    (signed    "Enclose as signed"     mime-editor/enclose-signed-region)
+    (encrypted "Enclose as encrypted"  mime-editor/enclose-encrypted-region)
+    (key       "Insert Public Key"     mime-editor/insert-key)
+    (split     "About split"           mime-editor/set-split)
+    (sign      "About sign"            mime-editor/set-sign)
+    (encrypt   "About encryption"      mime-editor/set-encrypt)
+    (preview   "Preview Message"       mime-editor/preview-message)
+    (level     "Toggle transfer-level" mime-editor/toggle-transfer-level)
+    )
   "MIME-edit menubar entry.")
 
 (defun mime-editor/define-menu-for-emacs19 ()
@@ -601,7 +603,7 @@ Tspecials means any character that matches with it in header must be quoted.")
          (reverse mime-editor/menu-list)
          ))
 
-;;; modified by Pekka Marjola <pema@niksula.hut.fi>
+;;; modified by Pekka Marjola <pema@iki.fi>
 ;;;    1995/9/5 (c.f. [tm-en:69])
 (defun mime-editor/define-menu-for-xemacs ()
   "Define menu for Emacs 19."
@@ -620,8 +622,7 @@ Tspecials means any character that matches with it in header must be quoted.")
 
 ;;; modified by Steven L. Baur <steve@miranova.com>
 ;;;    1995/12/6 (c.f. [tm-en:209])
-(if (and (string-match "XEmacs\\|Lucid" emacs-version)
-        (not (boundp 'mime-editor/popup-menu-for-xemacs)))
+(if (and running-xemacs (not (boundp 'mime-editor/popup-menu-for-xemacs)))
     (setq mime-editor/popup-menu-for-xemacs
          (append '("MIME Commands" "---")
                  (mapcar (function (lambda (item)
@@ -686,7 +687,7 @@ Following commands are available in addition to major mode commands:
 \\[mime-editor/insert-key]     insert PGP public key.
 \\[mime-editor/preview-message]        preview editing MIME message.
 \\[mime-editor/exit]   exit and translate into a MIME compliant message.
-\\[mime-editor/maybe-translate]        exit, translate and run the original command.
+\\[mime-editor/maybe-translate]        exit and translate if in MIME mode, then split.
 \\[mime-editor/help]   show this help.
 
 Additional commands are available in some major modes:
@@ -713,10 +714,6 @@ User customizable variables (not documented all of them):
  mime-prefix
     Specifies a key prefix for MIME minor mode commands.
 
- mime-signature-file
-    Specifies a signature file to be included as part of a multipart
-    message.
-
  mime-ignore-preceding-spaces
     Preceding white spaces in a message body are ignored if non-nil.
 
@@ -730,10 +727,6 @@ User customizable variables (not documented all of them):
     Hide a non-textual body message encoded in base64 after insertion
     if non-nil.
 
- mime-string-encoder
-    Specifies a function to encode a string for given encoding method.
-    The method is a form of (CHARSET . ENCODING).
-
  mime-voice-recorder
     Specifies a function to record a voice message and return a buffer
     that contains it.  The function mime-voice-recorder-for-sun is for
@@ -757,21 +750,27 @@ User customizable variables (not documented all of them):
       (error "You are already editing a MIME message.")
     (setq mime/editor-mode-flag t)
     ;; Remember old key bindings.
-    (make-local-variable 'mime/editor-mode-old-local-map)
-    (setq mime/editor-mode-old-local-map (current-local-map))
-    ;; Add MIME commands to current local map.
-    (use-local-map (copy-keymap (current-local-map)))
+    (if running-xemacs
+       nil
+      (make-local-variable 'mime/editor-mode-old-local-map)
+      (setq mime/editor-mode-old-local-map (current-local-map))
+      ;; Add MIME commands to current local map.
+      (use-local-map (copy-keymap (current-local-map)))
+      )
     (if (not (lookup-key (current-local-map) mime-prefix))
-       (define-key (current-local-map) mime-prefix (make-sparse-keymap)))
-    (mime-editor/define-keymap (lookup-key (current-local-map) mime-prefix))
+       (define-key (current-local-map) mime-prefix mime-editor/mime-map))
+
+    ;; Set transfer level into mode line
+    ;;
+    (setq mime-editor/transfer-level-string
+         (mime/encoding-name mime-editor/transfer-level 'not-omit))
+    (force-mode-line-update)
     
     ;; Define menu.  Menus for other emacs implementations are
     ;; welcome.
-    ;; modified by Pekka Marjola <pema@niksula.hut.fi>
-    ;;         1995/9/5 (c.f. [tm-eng:69])
-    (cond ((string-match "XEmacs\\|Lucid" emacs-version)
+    (cond (running-xemacs
           (mime-editor/define-menu-for-xemacs))
-         ((string-match "^19\\." emacs-version)
+         ((>= emacs-major-version 19)
           (mime-editor/define-menu-for-emacs19)
           ))
     ;; end
@@ -812,18 +811,10 @@ just return to previous mode."
          (mime-editor/translate-buffer)))
     ;; Restore previous state.
     (setq mime/editor-mode-flag nil)
-    (use-local-map mime/editor-mode-old-local-map)
-    
-    ;; modified by Pekka Marjola <pema@niksula.hut.fi>
-    ;; 1995/9/5 (c.f. [tm-eng:69])
-    (if (string-match "XEmacs\\|Lucid" emacs-version)
-       (progn
-         (delete-menu-item (list mime-editor/menu-title))
-                                       ; should rather be const
-          ;; (while mime-editor/xemacs-old-bindings
-          ;;   (eval (pop mime-editor/xemacs-old-bindings)))
-         (local-unset-key mime-prefix)))
-    ;; end
+    (cond (running-xemacs
+          (delete-menu-item (list mime-editor/menu-title)))
+         (t
+          (use-local-map mime/editor-mode-old-local-map)))
     
     (setq selective-display mime/editor-mode-old-selective-display)
     (set-buffer-modified-p (buffer-modified-p))
@@ -950,32 +941,17 @@ Charset is automatically obtained from the `mime/lc-charset-alist'."
       )))
 
 (defun mime-editor/insert-signature (&optional arg)
-  "Insert a signature file specified by mime-signature-file."
+  "Insert a signature file."
   (interactive "P")
-  (let ((signature
-        (expand-file-name
-         (if arg
-             (read-file-name "Insert your signature: "
-                             (concat signature-file-name "-")
-                             signature-file-name
-                             nil)
-           (signature/get-signature-file-name))))
-       )
-    (if signature-insert-at-eof
-       (goto-char (point-max))
-      )
-    (apply (function mime-editor/insert-tag)
-          (mime-find-file-type signature))
-    (if (file-readable-p signature)
-       (progn
-         (goto-char (point-max))
-         (if (not (bolp))
-             (insert "\n"))
-         (delete-blank-lines)
-         (insert-file-contents signature)
-         (set-buffer-modified-p (buffer-modified-p))
-                                       ; force mode line update
-         ))))
+  (let ((signature-insert-hook
+         (function
+          (lambda ()
+            (apply (function mime-editor/insert-tag)
+                   (mime-find-file-type signature-file-name))
+            )))
+        )
+    (insert-signature arg)
+    ))
 
 \f
 ;; Insert a new tag around a point.
@@ -1097,7 +1073,8 @@ Optional argument ENCODING specifies an encoding method such as base64."
        (insert-buffer-substring buffer)
        ;; Encode binary message if necessary.
        (if encoding
-           (mime-encode-region encoding start (point-max))))
+           (mime-encode-region start (point-max) encoding)
+         ))
       (if hide-p
          (progn
            (mime-flag-region (point-min) (1- (point-max)) ?\^M)
@@ -1403,30 +1380,6 @@ Parameter must be '(PROMPT CHOICE1 (CHOISE2 ...))."
          (mime-prompt-for-parameters-1 (cdr (assoc answer (cdr parameter)))))
     ))
 
-(defun mime-encode-string (encoding string)
-  "Using ENCODING encode a STRING.
-If the STRING is too long, the encoded string may be broken into
-several lines."
-  (save-excursion
-    (set-buffer (get-buffer-create " *MIME encoding*"))
-    (erase-buffer)
-    (insert string)
-    (mime-encode-region encoding (point-min) (point-max))
-    (prog1
-       (buffer-substring (point-min) (point-max))
-      (kill-buffer (current-buffer)))))
-
-(defun mime-decode-string (encoding string)
-  "Using ENCODING decode a STRING."
-  (save-excursion
-    (set-buffer (get-buffer-create " *MIME decoding*"))
-    (erase-buffer)
-    (insert string)
-    (mime-decode-region encoding (point-min) (point-max))
-    (prog1
-       (buffer-substring (point-min) (point-max))
-      (kill-buffer (current-buffer)))))
-
 (defun mime-flag-region (from to flag)
   "Hides or shows lines from FROM to TO, according to FLAG.
 If FLAG is `\\n' (newline character) then text is shown,
@@ -1443,14 +1396,17 @@ while if FLAG is `\\^M' (control-M) the text is hidden."
 ;;; @ Translate the tagged MIME messages into a MIME compliant message.
 ;;;
 
+(defvar mime-editor/translate-buffer-hook
+  '(mime-editor/pgp-enclose-buffer
+    mime/encode-message-header
+    mime-editor/translate-body))
+
 (defun mime-editor/translate-buffer ()
   "Encode the tagged MIME message in current buffer in MIME compliant message."
   (interactive)
   (if (catch 'mime-editor/error
        (save-excursion
-         (mime/encode-message-header)
-         (mime-editor/translate-body)
-         (mime-editor/pgp-processing)
+         (run-hooks 'mime-editor/translate-buffer-hook)
          ))
       (progn
        (undo)
@@ -1513,17 +1469,15 @@ while if FLAG is `\\^M' (control-M) the text is hidden."
                        (mime-editor/sign-pgp-elkins bb eb boundary)
                        )
                       ((eq mime-editor/signing-type 'pgp-kazu)
-                       (mime-editor/process-pgp-kazu 'mc-sign
-                                                     bb eb boundary)
+                       (mime-editor/sign-pgp-kazu bb eb boundary)
                        )
                       ))
                ((string= type "encrypted")
-                (cond ((eq mime-editor/signing-type 'pgp-elkins)
+                (cond ((eq mime-editor/encrypting-type 'pgp-elkins)
                        (mime-editor/encrypt-pgp-elkins bb eb boundary)
                        )
-                      ((eq mime-editor/signing-type 'pgp-kazu)
-                       (mime-editor/process-pgp-kazu 'mc-encrypt
-                                                     bb eb boundary)
+                      ((eq mime-editor/encrypting-type 'pgp-kazu)
+                       (mime-editor/encrypt-pgp-kazu bb eb boundary)
                        )))
                (t
                 (setq boundary
@@ -1537,14 +1491,17 @@ while if FLAG is `\\^M' (control-M) the text is hidden."
                 ))
          boundary))))
 
+
+(autoload 'mc-pgp-lookup-key "mc-pgp")
+(autoload 'mc-pgp-sign-region "mc-pgp")
+(autoload 'mc-pgp-encrypt-region "mc-pgp")
+
 (defun tm:mc-pgp-generic-parser (result)
   (let ((ret (mc-pgp-generic-parser result)))
     (if (consp ret)
        (vector (car ret)(cdr ret))
       )))
 
-(autoload 'mc-pgp-lookup-key "mc-pgp")
-
 (defun tm:mc-process-region
   (beg end passwd program args parser &optional buffer boundary)
   (let ((obuf (current-buffer))
@@ -1684,36 +1641,52 @@ Content-Transfer-Encoding: 7bit
 (defun mime-editor/encrypt-pgp-elkins (beg end boundary)
   (save-excursion
     (save-restriction
-      (narrow-to-region beg end)
-      (let* ((ret
-             (mime-editor/translate-region beg end boundary))
-            (ctype    (car ret))
-            (encoding (nth 1 ret))
-            (parts    (nth 3 ret))
-            (pgp-boundary (concat "pgp-" boundary))
-            )
-       (goto-char beg)
-       (insert (format "Content-Type: %s\n" ctype))
-       (if encoding
-           (insert (format "Content-Transfer-Encoding: %s\n" encoding))
-         )
-       (insert "\n")
-       (if (null
-            (progn
-              (goto-char beg)
-              (insert "=\n")
-              (prog1
-                  (let ((mail-header-separator "="))
-                    (call-interactively 'mc-encrypt)
-                    )
-                (goto-char beg)
-                (and (search-forward "=\n")
-                     (replace-match ""))
-                )))
-           (throw 'mime-editor/error 'pgp-error)
-         )
-       (goto-char beg)
-       (insert (format "--[[multipart/encrypted;
+      (let ((from (rfc822/get-field-body "From"))
+           (to (rfc822/get-field-body "To"))
+           (cc (rfc822/get-field-body "cc"))
+           recipients)
+       (narrow-to-region beg end)
+       (let* ((ret
+               (mime-editor/translate-region beg end boundary))
+              (ctype    (car ret))
+              (encoding (nth 1 ret))
+              (parts    (nth 3 ret))
+              (pgp-boundary (concat "pgp-" boundary))
+              )
+         (goto-char beg)
+         (if (and (stringp from)
+                  (not (string-equal from "")))
+             (insert (format "From: %s\n" from))
+           )
+         (if (and (stringp to)
+                  (not (string-equal to "")))
+             (progn
+               (insert (format "To: %s\n" to))
+               (setq recipients to)
+               ))
+         (if (and (stringp cc)
+                  (not (string-equal cc "")))
+             (progn
+               (insert (format "cc: %s\n" cc))
+               (if recipients
+                   (setq recipients (concat recipients "," cc))
+                 (setq recipients cc)
+                 )))
+         (insert (format "Content-Type: %s\n" ctype))
+         (if encoding
+             (insert (format "Content-Transfer-Encoding: %s\n" encoding))
+           )
+         (insert "\n")
+         (if (null
+              (let ((mc-pgp-always-sign 'never))
+                (mc-pgp-encrypt-region
+                 (mc-split "\\([ \t\n]*,[ \t\n]*\\)+" recipients)
+                 (point-min) (point-max) from nil)
+                ))
+             (throw 'mime-editor/error 'pgp-error)
+           )
+         (goto-char beg)
+         (insert (format "--[[multipart/encrypted;
  boundary=\"%s\";
  protocol=\"application/pgp-encrypted\"][7bit]]
 --%s
@@ -1724,12 +1697,11 @@ Content-Type: application/octet-stream
 Content-Transfer-Encoding: 7bit
 
 " pgp-boundary pgp-boundary pgp-boundary))
-       (goto-char (point-max))
-       (insert (format "\n--%s--\n" pgp-boundary))
-       ))
-    ))
+         (goto-char (point-max))
+         (insert (format "\n--%s--\n" pgp-boundary))
+         )))))
 
-(defun mime-editor/process-pgp-kazu (type beg end boundary)
+(defun mime-editor/sign-pgp-kazu (beg end boundary)
   (save-excursion
     (save-restriction
       (narrow-to-region beg end)
@@ -1745,26 +1717,66 @@ Content-Transfer-Encoding: 7bit
            (insert (format "Content-Transfer-Encoding: %s\n" encoding))
          )
        (insert "\n")
-       (if (null
-            (progn
-              (goto-char beg)
-              (insert "=\n")
-              (prog1
-                  (let ((mail-header-separator "="))
-                    (call-interactively type)
-                    )
-                (goto-char beg)
-                (and (search-forward "=\n")
-                     (replace-match ""))
-                )))
+       (or (as-binary-process (mc-pgp-sign-region beg (point-max)))
            (throw 'mime-editor/error 'pgp-error)
-         )
+           )
        (goto-char beg)
        (insert
         "--[[application/pgp; format=mime][7bit]]\n")
        ))
     ))
 
+(defun mime-editor/encrypt-pgp-kazu (beg end boundary)
+  (save-excursion
+    (let ((from (rfc822/get-field-body "From"))
+         (to (rfc822/get-field-body "To"))
+         (cc (rfc822/get-field-body "cc"))
+         recipients)
+      (save-restriction
+       (narrow-to-region beg end)
+       (let* ((ret
+               (mime-editor/translate-region beg end boundary))
+              (ctype    (car ret))
+              (encoding (nth 1 ret))
+              (parts    (nth 3 ret))
+              )
+         (goto-char beg)
+         (if (and (stringp from)
+                  (not (string-equal from "")))
+             (insert (format "From: %s\n" from))
+           )
+         (if (and (stringp to)
+                  (not (string-equal to "")))
+             (progn
+               (insert (format "To: %s\n" to))
+               (setq recipients to)
+               ))
+         (if (and (stringp cc)
+                  (not (string-equal cc "")))
+             (progn
+               (insert (format "cc: %s\n" cc))
+               (if recipients
+                   (setq recipients (concat recipients "," cc))
+                 (setq recipients cc)
+                 )))
+         (insert (format "Content-Type: %s\n" ctype))
+         (if encoding
+             (insert (format "Content-Transfer-Encoding: %s\n" encoding))
+           )
+         (insert "\n")
+         (or (as-binary-process
+              (mc-pgp-encrypt-region
+               (mc-split "\\([ \t\n]*,[ \t\n]*\\)+" recipients)
+               beg (point-max))
+              )
+             (throw 'mime-editor/error 'pgp-error)
+             )
+         (goto-char beg)
+         (insert
+          "--[[application/pgp; format=mime][7bit]]\n")
+         ))
+      )))
+
 (defun mime-editor/translate-body ()
   "Encode the tagged MIME body in current buffer in MIME compliant message."
   (interactive)
@@ -1903,74 +1915,82 @@ Content-Transfer-Encoding: 7bit
       ;; Remove extra whitespaces after the tag.
       (if (looking-at "[ \t]+$")
          (delete-region (match-beginning 0) (match-end 0)))
-      (cond ((= (following-char) ?\^M)
-            ;; It must be image, audio or video.
-            (let ((beg (point))
-                  (end (mime-editor/content-end)))
-              ;; Insert explicit MIME tags after hidden messages.
-              (forward-line 1)
-              (if (and (not (eobp))
-                       (not (looking-at mime-editor/single-part-tag-regexp)))
-                  (progn
-                    (insert (mime-make-text-tag) "\n")
-                    (forward-line -1)  ;Process it again as text.
+      (cond
+       ((= (following-char) ?\^M)
+       ;; It must be image, audio or video.
+       (let ((beg (point))
+             (end (mime-editor/content-end)))
+         ;; Insert explicit MIME tags after hidden messages.
+         (forward-line 1)
+         (if (and (not (eobp))
+                  (not (looking-at mime-editor/single-part-tag-regexp)))
+             (progn
+               (insert (mime-make-text-tag) "\n")
+               (forward-line -1)       ;Process it again as text.
+               ))
+         ;; Show a hidden message.  The point is not altered
+         ;; after the conversion.
+         (mime-flag-region beg end ?\n)
+         ))
+       ((mime-test-content-type contype "message")
+       ;; Content-type "message" should be sent as is.
+       (forward-line 1)
+       )
+       ((mime-test-content-type contype "text")
+       ;; Define charset for text if necessary.
+       (setq charset (or charset (mime-editor/choose-charset)))
+       (mime-editor/define-charset charset)
+       (cond ((string-equal contype "text/x-rot13-47")
+              (save-excursion
+                (forward-line)
+                (set-mark (point))
+                (goto-char (mime-editor/content-end))
+                (tm:caesar-region)
+                ))
+             ((string-equal contype "text/enriched")
+              (save-excursion
+                (let ((beg (progn
+                             (forward-line)
+                             (point)))
+                      (end (mime-editor/content-end))
+                      )
+                  (enriched-encode beg end)
+                  (goto-char beg)
+                  (if (search-forward "\n\n")
+                      (delete-region beg (match-end 0))
+                    )
+                  ))))
+       ;; Point is now on current tag.
+       ;; Define encoding and encode text if necessary.
+       (or encoding    ;Encoding is not specified.
+           (let* ((encoding
+                   (cdr
+                    (assoc charset
+                           mime-editor/charset-default-encoding-alist)
                     ))
-              ;; Show a hidden message.  The point is not altered
-              ;; after the conversion.
-              (mime-flag-region beg end ?\n)))
-           ((mime-test-content-type contype "message")
-            ;; Content-type "message" should be sent as is.
-            (forward-line 1))
-           ((mime-test-content-type contype "text")
-            ;; Define charset for text if necessary.
-            (setq charset (or charset (mime-editor/choose-charset)))
-            (mime-editor/define-charset charset)
-            (if (string-equal contype "text/x-rot13-47")
-                (save-excursion
-                  (forward-line)
-                  (set-mark (point))
-                  (goto-char (mime-editor/content-end))
-                  (tm:caesar-region)
-                  ))
-            ;; Point is now on current tag.
-            ;; Define encoding and encode text if necessary.
-            (if (null encoding)        ;Encoding is not specified.
-                (let* ((encoding
-                        (cdr
-                         (assoc charset mime/charset-default-encoding-alist)
-                         ))
-                       (beg (mime-editor/content-beginning))
-                       (end (mime-editor/content-end))
-                       (body (buffer-substring beg end))
-                       (encoded (funcall mime-string-encoder
-                                         (cons charset encoding) body)))
-                  (if (not (string-equal body encoded))
-                      (progn
-                        (goto-char beg)
-                        (delete-region beg end)
-                        (insert encoded)
-                        (goto-char beg)))
-                  (mime-editor/define-encoding encoding)))
-            (forward-line 1))
-           ((null encoding)            ;Encoding is not specified.
-            ;; Application, image, audio, video, and any other
-            ;; unknown content-type without encoding should be
-            ;; encoded.
-            (let* ((encoding "base64") ;Encode in BASE64 by default.
-                   (beg (mime-editor/content-beginning))
-                   (end (mime-editor/content-end))
-                   (body (buffer-substring beg end))
-                   (encoded (funcall mime-string-encoder
-                                     (cons nil encoding) body)))
-              (if (not (string-equal body encoded))
-                  (progn
-                    (goto-char beg)
-                    (delete-region beg end)
-                    (insert encoded)
-                    (goto-char beg)))
-              (mime-editor/define-encoding encoding))
-            (forward-line 1))
-           )
+                  (beg (mime-editor/content-beginning))
+                  )
+             (mime-charset-encode-region beg (mime-editor/content-end)
+                                         charset)
+             (mime-encode-region beg (mime-editor/content-end) encoding)
+             (mime-editor/define-encoding encoding)
+             ))
+       (forward-line 1)
+       )
+       ((null encoding)                ;Encoding is not specified.
+       ;; Application, image, audio, video, and any other
+       ;; unknown content-type without encoding should be
+       ;; encoded.
+       (let* ((encoding "base64")      ;Encode in BASE64 by default.
+              (beg (mime-editor/content-beginning))
+              (end (mime-editor/content-end))
+              (body (buffer-substring beg end))
+              )
+         (mime-encode-region beg end encoding)
+         (mime-editor/define-encoding encoding))
+       (forward-line 1)
+       )
+       )
       )))
 
 (defun mime-delete-field (field)
@@ -1987,93 +2007,6 @@ Content-Transfer-Encoding: 7bit
 ;;; Platform dependent functions
 ;;;
 
-;; Emacs 18 implementations
-
-(defun mime-string-encoder-for-emacs18 (method string)
-  "For given METHOD that is a cons of charset and encoding, encode a STRING."
-  (let ((charset (car method))
-       (encoding (cdr method)))
-    (cond ((stringp encoding)
-          (mime-encode-string encoding string))
-         ;; Return string without any encoding.
-         (t string)
-         )))
-
-\f
-;; Emacs 19 implementations
-
-(defun mime-string-encoder-for-emacs19 (method string)
-  "For given METHOD that is a cons of charset and encoding, encode a STRING."
-  (let ((charset (car method))
-       (encoding (cdr method)))
-    (cond ((stringp encoding)
-          (mime-encode-string encoding string))
-         ;; Return string without any encoding.
-         (t string)
-         )))
-
-\f
-;; NEmacs implementations
-
-(defun mime-string-encoder-for-nemacs (method string)
-  "For given METHOD that is a cons of charset and encoding, encode a STRING.
-US-ASCII and ISO-2022-JP are supported on NEmacs."
-  (let ((charset (car method))
-       (encoding (cdr method)))
-    (cond ((stringp encoding)
-          (mime-encode-string encoding
-                              ;; Convert internal (EUC) to JIS code.
-                              (convert-string-kanji-code string 3 2)
-                              ))
-         ;; NEmacs can convert into ISO-2022-JP automatically,
-         ;; but can do it myself as follows:
-         ;;(t (convert-string-kanji-code string 3 2))
-
-         ;; Return string without any encoding.
-         (t string)
-         )))
-
-\f
-;; Mule implementations
-;; Thanks to contributions by wkenji@flab.fujitsu.co.jp (Kenji
-;; WAKAMIYA) and handa@etl.go.jp (Kenichi Handa).
-
-(defun mime-string-encoder-for-mule (method string)
-  "For given METHOD that is a cons of charset and encoding, encode a
-STRING.  US-ASCII, ISO-8859-* (except for ISO-8859-6), ISO-2022-JP,
-ISO-2022-JP-2 and ISO-2022-INT-1 are supported on Mule.  Either of
-charset ISO-2022-JP-2 or ISO-2022-INT-1 is used for multilingual
-text."
-  (let* ((charset (car method))
-        (encoding (cdr method))
-        (coding-system
-         (cdr (assoc (and (stringp charset) (upcase charset))
-                     '(("ISO-8859-1" . *ctext*)
-                       ("ISO-8859-2" . *iso-8859-2*)
-                       ("ISO-8859-3" . *iso-8859-3*)
-                       ("ISO-8859-4" . *iso-8859-4*)
-                       ("ISO-8859-5" . *iso-8859-5*)
-                       ;;("ISO-8859-6" . *iso-8859-6*)
-                       ("ISO-8859-7" . *iso-8859-7*)
-                       ("ISO-8859-8" . *iso-8859-8*)
-                       ("ISO-8859-9" . *iso-8859-9*)
-                       ("ISO-2022-JP" . *junet*)
-                       ("ISO-2022-JP-2" . *iso-2022-ss2-7*)
-                       ("ISO-2022-KR" . *korean-mail*)
-                       ("ISO-2022-INT-1" . *iso-2022-int-1*)
-                       )))))
-    ;; In bilingual environment it may be unnecessary to convert the
-    ;; coding system of the string unless transfer encoding is
-    ;; required since such conversion may be performed by mule
-    ;; automatically.
-    (if (not (null coding-system))
-       (setq string (code-convert-string string *internal* coding-system)))
-    (if (stringp encoding)
-       (setq string (mime-encode-string encoding string)))
-    string
-    ))
-
-\f
 ;; Sun implementations
 
 (defun mime-voice-recorder-for-sun ()
@@ -2254,6 +2187,27 @@ a recording host instead of local host."
     (message "This message is not enabled to split.")
     ))
 
+(defun mime-editor/toggle-transfer-level (&optional transfer-level)
+  "Toggle transfer-level is 7bit or 8bit through.
+
+Optional TRANSFER-LEVEL is a number of transfer-level, 7 or 8."
+  (interactive)
+  (if (numberp transfer-level)
+      (setq mime-editor/transfer-level transfer-level)
+    (if (< mime-editor/transfer-level 8)
+       (setq mime-editor/transfer-level 8)
+      (setq mime-editor/transfer-level 7)
+      ))
+  (setq mime-editor/charset-default-encoding-alist
+       (mime/make-charset-default-encoding-alist
+        mime-editor/transfer-level))
+  (message (format "Current transfer-level is %d bit"
+                  mime-editor/transfer-level))
+  (setq mime-editor/transfer-level-string
+       (mime/encoding-name mime-editor/transfer-level 'not-omit))
+  (force-mode-line-update)
+  )
+
 
 ;;; @ pgp
 ;;;
@@ -2264,9 +2218,12 @@ a recording host instead of local host."
     (y-or-n-p "Do you want to sign?")
     ))
   (if arg
-      (progn
-       (setq mime-editor/pgp-processing 'sign)
-       (message "This message will be signed.")
+      (if mime-editor/signing-type
+         (progn
+           (setq mime-editor/pgp-processing 'sign)
+           (message "This message will be signed.")
+           )
+       (message "Please specify signing type.")
        )
     (if (eq mime-editor/pgp-processing 'sign)
        (setq mime-editor/pgp-processing nil)
@@ -2280,9 +2237,12 @@ a recording host instead of local host."
     (y-or-n-p "Do you want to encrypt?")
     ))
   (if arg
-      (progn
-       (setq mime-editor/pgp-processing 'encrypt)
-       (message "This message will be encrypt.")
+      (if mime-editor/encrypting-type
+         (progn
+           (setq mime-editor/pgp-processing 'encrypt)
+           (message "This message will be encrypt.")
+           )
+       (message "Please specify encrypting type.")
        )
     (if (eq mime-editor/pgp-processing 'encrypt)
        (setq mime-editor/pgp-processing nil)
@@ -2293,32 +2253,22 @@ a recording host instead of local host."
 (defvar mime-editor/pgp-processing nil)
 (make-variable-buffer-local 'mime-editor/pgp-processing)
 
-(defun mime-editor/call-mc (command)
-  (let* ((header (rfc822/get-header-string-except
-                 "^Content-Type:" mail-header-separator)))
-    (goto-char (point-min))
-    (if (search-forward mail-header-separator)
-       (replace-match "")
-      )
-    (goto-char (point-min))
-    (insert header)
-    (insert "Content-Type: application/pgp; format=mime\n")
-    (insert mail-header-separator)
-    (insert "\n")
-    (if (null (call-interactively command))
-       (throw 'mime-editor/error 'pgp-error)
-      )
-    ))
-
-(defun mime-editor/pgp-processing ()
-  (let ((command
-        (cdr (assq mime-editor/pgp-processing
-                   '((sign    . mc-sign)
-                     (encrypt . mc-encrypt)
-                     )))))
-    (and command
-        (mime-editor/call-mc command)
-        )))
+(defun mime-editor/pgp-enclose-buffer ()
+  (let ((beg (save-excursion
+              (goto-char (point-min))
+              (if (search-forward (concat "\n" mail-header-separator "\n"))
+                  (match-end 0)
+                )))
+       (end (point-max))
+       )
+    (if beg
+       (cond ((eq mime-editor/pgp-processing 'sign)
+              (mime-editor/enclose-signed-region beg end)
+              )
+             ((eq mime-editor/pgp-processing 'encrypt)
+              (mime-editor/enclose-encrypted-region beg end)
+              ))
+      )))
 
 
 ;;; @ split
@@ -2352,92 +2302,46 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
              (make-temp-name
               (expand-file-name "tm-draft" mime/tmp-dir))))
         (separator mail-header-separator)
-        (config
-         (eval (cdr (assq major-mode mime-editor/window-config-alist))))
         (id (concat "\""
                     (replace-space-with-underline (current-time-string))
                     "@" (system-name) "\"")))
     (run-hooks 'mime-editor/before-split-hook)
-    (let* ((header (rfc822/get-header-string-except
-                   mime-editor/split-ignored-field-regexp separator))
-          (subject (mail-fetch-field "subject"))
-          (total (+ (/ lines mime-editor/message-max-length)
-                    (if (> (mod lines mime-editor/message-max-length) 0)
-                        1)))
-          (the-buf (current-buffer))
-          (buf (get-buffer "*tmp-send*"))
-          (command
-           (or cmd
-               (cdr
-                (assq major-mode
-                      mime-editor/split-message-sender-alist))
-               (cdr
-                (assq major-mode
-                      mime-editor/message-default-sender-alist))
-               ))
-          data)
-      (goto-char (point-min))
-      (if (re-search-forward (concat "^" (regexp-quote separator) "$")
-                            nil t)
-         (replace-match "")
-       )
-      (if buf
-         (progn
-           (switch-to-buffer buf)
-           (erase-buffer)
-           (switch-to-buffer the-buf)
-           )
-       (setq buf (get-buffer-create "*tmp-send*"))
-       )
-      (switch-to-buffer buf)
-      (make-local-variable 'mail-header-separator)
-      (setq mail-header-separator separator)
-      (switch-to-buffer the-buf)
-      (goto-char (point-min))
-      (re-search-forward "^$" nil t)
-      (let ((mime-editor/partial-number 1))
-       (setq data (buffer-substring
-                   (point-min)
-                   (progn
-                     (goto-line mime-editor/message-max-length)
-                     (point))
-                   ))
-       (delete-region (point-min)(point))
-       (switch-to-buffer buf)
-       (mime-editor/insert-partial-header
-        header subject id mime-editor/partial-number total separator)
-       (insert data)
-       (save-excursion
-         (save-restriction
-           (goto-char (point-min))
-           (search-forward (concat "\n" mail-header-separator "\n"))
-           (narrow-to-region
-            (match-end 0)
-            (if (re-search-forward "^$" nil t)
-                (match-beginning 0)
-              (point-max)
+    (let ((the-buf (current-buffer))
+         (copy-buf (get-buffer-create " *Original Message*"))
+         (header (rfc822/get-header-string-except
+                  mime-editor/split-ignored-field-regexp separator))
+         (subject (mail-fetch-field "subject"))
+         (total (+ (/ lines mime-editor/message-max-length)
+                   (if (> (mod lines mime-editor/message-max-length) 0)
+                       1)))
+         (command
+          (or cmd
+              (cdr
+               (assq major-mode
+                     mime-editor/split-message-sender-alist))
               ))
-           (goto-char (point-min))
-           (while (re-search-forward
-                   mime-editor/split-blind-field-regexp nil t)
-             (delete-region (match-beginning 0)
-                            (let ((e (rfc822/field-end)))
-                              (if (< e (point-max))
-                                  (1+ e)
-                                e)))
-             )
-           ))
-       (save-excursion
-         (message (format "Sending %d/%d..."
-                          mime-editor/partial-number total))
-         (call-interactively command)
-         (message (format "Sending %d/%d... done"
-                          mime-editor/partial-number total))
-         )
+         (mime-editor/partial-number 1)
+         data)
+      (save-excursion
+       (set-buffer copy-buf)
        (erase-buffer)
-       (switch-to-buffer the-buf)
-       (setq mime-editor/partial-number 2)
-       (while (< mime-editor/partial-number total)
+       (insert-buffer the-buf)
+       (save-restriction
+         (if (re-search-forward
+              (concat "^" (regexp-quote separator) "$") nil t)
+             (let ((he (match-beginning 0)))
+               (replace-match "")
+               (narrow-to-region (point-min) he)
+               ))
+         (goto-char (point-min))
+         (while (re-search-forward mime-editor/split-blind-field-regexp nil t)
+           (delete-region (match-beginning 0)
+                          (1+ (rfc822/field-end)))
+           )))
+      (while (< mime-editor/partial-number total)
+       (erase-buffer)
+       (save-excursion
+         (set-buffer copy-buf)
          (setq data (buffer-substring
                      (point-min)
                      (progn
@@ -2445,28 +2349,36 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
                        (point))
                      ))
          (delete-region (point-min)(point))
-         (switch-to-buffer buf)
-         (mime-editor/insert-partial-header
-          header subject id mime-editor/partial-number total separator)
-         (insert data)
-         (save-excursion
-           (message (format "Sending %d/%d..."
-                            mime-editor/partial-number total))
-           (call-interactively command)
-           (message (format "Sending %d/%d... done"
-                            mime-editor/partial-number total))
-           )
-         (erase-buffer)
-         (switch-to-buffer the-buf)
-         (setq mime-editor/partial-number
-               (1+ mime-editor/partial-number))
          )
-       (goto-char (point-min))
        (mime-editor/insert-partial-header
         header subject id mime-editor/partial-number total separator)
+       (insert data)
+       (save-excursion
+         (message (format "Sending %d/%d..."
+                          mime-editor/partial-number total))
+         (call-interactively command)
+         (message (format "Sending %d/%d... done"
+                          mime-editor/partial-number total))
+         )
+       (setq mime-editor/partial-number
+             (1+ mime-editor/partial-number))
+       )
+      (erase-buffer)
+      (save-excursion
+       (set-buffer copy-buf)
+       (setq data (buffer-string))
+       (erase-buffer)
+       )
+      (mime-editor/insert-partial-header
+       header subject id mime-editor/partial-number total separator)
+      (insert data)
+      (save-excursion
        (message (format "Sending %d/%d..."
                         mime-editor/partial-number total))
-       ))))
+       (message (format "Sending %d/%d... done"
+                        mime-editor/partial-number total))
+       )
+      )))
 
 (defun mime-editor/maybe-split-and-send (&optional cmd)
   (interactive)
@@ -2593,17 +2505,160 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
           )
 
 
-;;; @ etc
+;;; @ edit again
 ;;;
 
-(defun replace-space-with-underline (str)
-  (mapconcat (function
-             (lambda (arg)
-               (char-to-string
-                (if (= arg 32)
-                    ?_
-                  arg)))) str "")
-  )
+(defun mime-editor::edit-again (code-conversion)
+  (save-excursion
+    (goto-char (point-min))
+    (let ((ctl (mime/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)
+             )
+           (cond
+            ((string-equal type "multipart")
+             (let ((boundary (assoc-value "boundary" params)))
+               (re-search-forward (concat "\n--" boundary) nil t)
+               (let ((bb (match-beginning 0)) eb tag)
+                 (setq tag (format "\n--<<%s>>-{" stype))
+                 (goto-char bb)
+                 (insert tag)
+                 (setq bb (+ bb (length tag)))
+                 (re-search-forward (concat "\n--" boundary "--") nil t)
+                 (setq eb (match-beginning 0))
+                 (replace-match (format "\n--}-<<%s>>" stype))
+                 (save-restriction
+                   (narrow-to-region bb eb)
+                   (goto-char (point-min))
+                   (while (re-search-forward
+                           (concat "\n--" boundary "\n") nil t)
+                     (let ((beg (match-beginning 0))
+                           end)
+                       (delete-region beg (match-end 0))
+                       (save-excursion
+                         (if (re-search-forward
+                              (concat "\n--" boundary) nil t)
+                             (setq end (match-beginning 0))
+                           (setq end (point-max))
+                           )
+                         (save-restriction
+                           (narrow-to-region beg end)
+                           (mime-editor::edit-again code-conversion)
+                           (goto-char (point-max))
+                           ))))
+                   ))
+               (goto-char (point-min))
+               (or (= (point-min) 1)
+                   (delete-region (point-min)
+                                  (if (re-search-forward "^$" nil t)
+                                      (match-end 0)
+                                    (point-min)
+                                    )))
+               ))
+            (t
+             (let* (charset
+                    (pstr
+                     (mapconcat (function
+                                 (lambda (attr)
+                                   (if (string-equal (car attr)
+                                                     "charset")
+                                       (progn
+                                         (setq charset (cdr attr))
+                                         "")
+                                     (concat ";" (car attr)
+                                             "=" (cdr attr))
+                                     )
+                                   ))
+                                params ""))
+                    encoding
+                    encoded)
+               (save-excursion
+                 (if (re-search-forward
+                      "Content-Transfer-Encoding:" nil t)
+                     (let ((beg (match-beginning 0))
+                           (hbeg (match-end 0))
+                           (end (rfc822/field-end)))
+                       (setq encoding
+                             (eliminate-top-spaces
+                              (rfc822/unfolding-string
+                               (buffer-substring hbeg end))))
+                       (if (or charset (string-equal type "text"))
+                           (progn
+                             (delete-region beg (1+ end))
+                             (goto-char (point-min))
+                             (if (search-forward "\n\n" nil t)
+                                 (progn
+                                   (mime-decode-region
+                                    (match-end 0)(point-max) encoding)
+                                   (setq encoded t
+                                         encoding nil)
+                                   )))))))
+               (if (or code-conversion encoded)
+                   (if charset
+                       (mime-charset-decode-region (point-min)(point-max)
+                                                   charset)
+                     (character-decode-region (point-min)(point-max)
+                                              mime/default-coding-system)
+                     ))
+               (let ((he
+                      (if (re-search-forward "^$" nil t)
+                          (match-end 0)
+                        (point-min)
+                        )))
+                 (if (= (point-min) 1)
+                     (progn
+                       (goto-char he)
+                       (insert
+                        (concat
+                         "\n"
+                         (mime-create-tag
+                          (concat type "/" stype pstr) encoding)
+                         ))
+                       )
+                   (delete-region (point-min) he)
+                   (insert
+                    (concat "\n"
+                            (mime-create-tag
+                             (concat type "/" stype pstr) encoding)
+                            ))
+                   ))
+               ))))
+       (if code-conversion
+           (character-decode-region (point-min) (point-max)
+                                    mime/default-coding-system)
+         )
+       ))))
+
+(defun mime/edit-again (&optional code-conversion no-separator no-mode)
+  (interactive)
+  (mime-editor::edit-again code-conversion)
+  (goto-char (point-min))
+  (save-restriction
+    (narrow-to-region (point-min)
+                     (if (re-search-forward "^$" nil t)
+                         (match-end 0)
+                       (point-max)
+                       ))
+    (goto-char (point-min))
+    (while (re-search-forward
+           "^\\(Content-.*\\|Mime-Version\\):" nil t)
+      (delete-region (match-beginning 0) (1+ (rfc822/field-end)))
+      ))
+  (or no-separator
+      (and (re-search-forward "^$")
+          (replace-match mail-header-separator)
+          ))
+  (or no-mode
+      (mime/editor-mode)
+      ))
 
 
 ;;; @ end