tm-ftp is merged to mime-play.el.
[elisp/semi.git] / mime-edit.el
index 15c1509..02d7cd9 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.54 $
+;; Version: $Revision: 0.70 $
 ;; Keywords: MIME, multimedia, multilingual, mail, news
 
 ;; This file is part of SEMI (SEMI is Emacs MIME Interfaces).
 ;; composed in the tagged MIME format are automatically translated
 ;; into a MIME compliant message when exiting the mode.
 
-;; Mule (a multilingual extension to Emacs 18 and 19) has a capability
-;; of handling multilingual text in limited ISO-2022 manner that is
-;; based on early experiences in Japanese Internet community and
-;; resulted in RFC 1468 (ISO-2022-JP charset for MIME).  In order to
-;; enable multilingual capability in single text message in MIME,
-;; charset of multilingual text written in Mule is declared as either
-;; `ISO-2022-JP-2' [RFC 1554].  Mule is required for reading the such
-;; messages.
+;; Mule (multilingual feature of Emacs 20 and multilingual extension
+;; for XEmacs 20) has a capability of handling multilingual text in
+;; limited ISO-2022 manner that is based on early experiences in
+;; Japanese Internet community and resulted in RFC 1468 (ISO-2022-JP
+;; charset for MIME).  In order to enable multilingual capability in
+;; single text message in MIME, charset of multilingual text written
+;; in Mule is declared as either `ISO-2022-JP-2' [RFC 1554].  Mule is
+;; required for reading the such messages.
 
 ;; This MIME composer can work with Mail mode, mh-e letter Mode, and
 ;; 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.54 1997-03-03 17:31:19 morioka Exp $")
+  "$Id: mime-edit.el,v 0.70 1997-03-07 14:06:53 morioka Exp $")
 
 (defconst mime-edit-version (get-version-string mime-edit-RCS-ID))
 
 ;;; @ variables
 ;;;
 
-(defvar mime-prefix "\C-c\C-x"
-  "*Keymap prefix for MIME commands.")
-
 (defvar mime-ignore-preceding-spaces nil
   "*Ignore preceding white spaces if non-nil.")
 
@@ -353,6 +350,7 @@ To insert a signature file automatically, call the function
   "*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
 ;;;
 
@@ -370,6 +368,8 @@ If encoding is nil, it is determined from its contents.")
     (iso-2022-jp       7 "base64")
     (iso-2022-kr       7 "base64")
     (euc-kr            8 "base64")
+    (cn-gb2312         8 "quoted-printable")
+    (cn-big5           8 "base64")
     (gb2312            8 "quoted-printable")
     (big5              8 "base64")
     (iso-2022-jp-2     7 "base64")
@@ -388,7 +388,7 @@ If encoding is nil, it is determined from its contents.")
 
 (defvar mime-transfer-level-string
   (mime-encoding-name mime-transfer-level 'not-omit)
-  "*A string formatted version of mime/defaul-transfer-level")
+  "A string formatted version of mime-transfer-level")
 (make-variable-buffer-local 'mime-transfer-level-string)
 
 (defun mime-make-charset-default-encoding-alist (transfer-level)
@@ -408,6 +408,7 @@ If encoding is nil, it is determined from its contents.")
   (mime-make-charset-default-encoding-alist mime-transfer-level))
 (make-variable-buffer-local 'mime-edit-charset-default-encoding-alist)
 
+
 ;;; @@ about message inserting
 ;;;
 
@@ -426,6 +427,7 @@ Each elements are regexp of field-name. [mime-edit.el]")
 (defvar mime-edit-message-inserter-alist nil)
 (defvar mime-edit-mail-inserter-alist nil)
 
+
 ;;; @@ about message splitting
 ;;;
 
@@ -495,6 +497,7 @@ If it is not specified for a major-mode,
 (defvar mime-tag-format-with-encoding "--[[%s][%s]]"
   "*Control-string making a MIME tag with encoding.")
 
+
 ;;; @@ multipart boundary
 ;;;
 
@@ -502,11 +505,24 @@ If it is not specified for a major-mode,
   "*Boundary of a multipart message.")
 
 
-;;; @@ buffer local variables
+;;; @@ optional header fields
 ;;;
 
-(defvar mime-edit-mode-old-local-map nil)
-(defvar mime/editing-buffer nil)
+(defvar mime-edit-insert-x-emacs-field t
+  "*If non-nil, insert X-Emacs header field.")
+
+(defvar mime-edit-x-emacs-value
+  (if running-xemacs
+      (concat emacs-version
+             (if (featurep 'mule)
+                 " with mule"
+               " without mule"))
+    (let ((ver (if (string-match "\\.[0-9]+$" emacs-version)
+                  (substring emacs-version 0 (match-beginning 0))
+                emacs-version)))
+      (if (featurep 'mule)
+         (concat "Emacs " ver ", MULE " mule-version)
+       ver))))
 
 \f
 ;;; @ constants
@@ -520,9 +536,6 @@ Tspecials means any character that matches with it in header must be quoted.")
   (concat "1.0 (generated by " mime-edit-version-name ")")
   "MIME version number.")
 
-(defconst mime-edit-mime-map (make-sparse-keymap)
-  "Keymap for MIME commands.")
-
 
 ;;; @ keymap and menu
 ;;;
@@ -530,66 +543,37 @@ 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)
 
-(defun mime-edit-define-keymap (keymap)
-  "Add mime-editor commands to KEYMAP."
-  (if (not (keymapp keymap))
-      nil
-    (define-key keymap "\C-t" 'mime-edit-insert-text)
-    (define-key keymap "\C-i" 'mime-edit-insert-file)
-    (define-key keymap "\C-e" 'mime-edit-insert-external)
-    (define-key keymap "\C-v" 'mime-edit-insert-voice)
-    (define-key keymap "\C-y" 'mime-edit-insert-message)
-    (define-key keymap "\C-m" 'mime-edit-insert-mail)
-    (define-key keymap "\C-w" 'mime-edit-insert-signature)
-    (define-key keymap "\C-s" 'mime-edit-insert-signature)
-    (define-key keymap "\C-k" 'mime-edit-insert-key)
-    (define-key keymap "t"    'mime-edit-insert-tag)
-    (define-key keymap "a"    'mime-edit-enclose-alternative-region)
-    (define-key keymap "p"    'mime-edit-enclose-parallel-region)
-    (define-key keymap "m"    'mime-edit-enclose-mixed-region)
-    (define-key keymap "d"    'mime-edit-enclose-digest-region)
-    (define-key keymap "s"    'mime-edit-enclose-signed-region)
-    (define-key keymap "e"    'mime-edit-enclose-encrypted-region)
-    (define-key keymap "q"    'mime-edit-enclose-quote-region)
-    (define-key keymap "7"    'mime-edit-set-transfer-level-7bit)
-    (define-key keymap "8"    'mime-edit-set-transfer-level-8bit)
-    (define-key keymap "/"    'mime-edit-set-split)
-    (define-key keymap "v"    'mime-edit-set-sign)
-    (define-key keymap "h"    'mime-edit-set-encrypt)
-    (define-key keymap "\C-p" 'mime-edit-preview-message)
-    (define-key keymap "\C-z" 'mime-edit-exit)
-    (define-key keymap "?"    'mime-edit-help)
-    ))
+(defvar mime-edit-prefix "\C-c\C-x"
+  "*Keymap prefix for MIME-Edit commands.")
 
-(mime-edit-define-keymap mime-edit-mime-map)
+(defvar mime-edit-map (make-sparse-keymap)
+  "Keymap for MIME commands.")
 
-(defun mime-edit-toggle-mode ()
-  (interactive)
-  (if mime-edit-mode-flag
-      (mime-edit-exit 'nomime)
-    (mime-edit-mode)
-    ))
-
-(cond (running-xemacs
-       (defconst mime-edit-minor-mime-map nil "Keymap for MIME commands.")
-       (or mime-edit-minor-mime-map
-          (progn
-            (setq mime-edit-minor-mime-map 
-                  (make-sparse-keymap 'mime-edit-minor-mime-map))
-            (define-key
-              mime-edit-minor-mime-map mime-prefix mime-edit-mime-map)
-            ))
-       (add-minor-mode 'mime-edit-mode-flag
-                      '((" MIME-Edit "  mime-transfer-level-string))
-                      mime-edit-minor-mime-map
-                      nil
-                      'mime-edit-toggle-mode)
-       )
-      (t
-       (set-alist 'minor-mode-alist
-                 'mime-edit-mode-flag
-                 '((" MIME-Edit "  mime-transfer-level-string))))
-      )
+(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)
 
 (defconst mime-edit-menu-title "MIME-Edit")
 
@@ -620,50 +604,71 @@ Tspecials means any character that matches with it in header must be quoted.")
     )
   "MIME-edit menubar entry.")
 
-(defun mime-edit-define-menu-for-emacs19 ()
-  "Define menu for Emacs 19."
-  (define-key (current-local-map) [menu-bar mime-edit]
-    (cons mime-edit-menu-title
-         (make-sparse-keymap mime-edit-menu-title)))
-  (mapcar (function
-          (lambda (item)
-            (define-key (current-local-map)
-              (vector 'menu-bar 'mime-edit (car item))
-              (cons (nth 1 item)(nth 2 item))
+(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])
+       (defun mime-edit-define-menu-for-xemacs ()
+        "Define menu for Emacs 19."
+        (cond ((featurep 'menubar)
+               (make-local-variable 'current-menubar)
+               (set-buffer-menubar current-menubar)
+               (add-submenu
+                nil
+                (cons mime-edit-menu-title
+                      (mapcar (function
+                               (lambda (item)
+                                 (vector (nth 1 item)(nth 2 item)
+                                         mime-edit-mode-flag)
+                                 ))
+                              mime-edit-menu-list)))
+               )))
+       
+       ;; modified by Steven L. Baur <steve@miranova.com>
+       ;;      1995/12/6 (c.f. [tm-en:209])
+       (or (boundp 'mime-edit-popup-menu-for-xemacs)
+          (setq mime-edit-popup-menu-for-xemacs
+                (append '("MIME Commands" "---")
+                        (mapcar (function (lambda (item)
+                                            (vector (nth 1 item)
+                                                    (nth 2 item)
+                                                    t)))
+                                mime-edit-menu-list)))
+          )
+       )
+      ((>= emacs-major-version 19)
+       (define-key mime-edit-mode-map [menu-bar mime-edit]
+        (cons mime-edit-menu-title
+              (make-sparse-keymap mime-edit-menu-title)))
+       (mapcar (function
+               (lambda (item)
+                 (define-key mime-edit-mode-map
+                   (vector 'menu-bar 'mime-edit (car item))
+                   (cons (nth 1 item)(nth 2 item))
+                   )
+                 ))
+              (reverse mime-edit-menu-list)
               )
-            ))
-         (reverse mime-edit-menu-list)
-         ))
+       ))
 
-;;; modified by Pekka Marjola <pema@iki.fi>
-;;;    1995/9/5 (c.f. [tm-en:69])
-(defun mime-edit-define-menu-for-xemacs ()
-  "Define menu for Emacs 19."
-  (cond ((featurep 'menubar)
-        (make-local-variable 'current-menubar)
-        (set-buffer-menubar current-menubar)
-        (add-submenu nil
-                     (cons mime-edit-menu-title
-                           (mapcar (function
-                                    (lambda (item)
-                                      (vector (nth 1 item)(nth 2 item)
-                                              mime-edit-mode-flag)
-                                      ))
-                                   mime-edit-menu-list)))
-        )))
-
-;;; modified by Steven L. Baur <steve@miranova.com>
-;;;    1995/12/6 (c.f. [tm-en:209])
-(if (and running-xemacs (not (boundp 'mime-edit-popup-menu-for-xemacs)))
-    (setq mime-edit-popup-menu-for-xemacs
-         (append '("MIME Commands" "---")
-                 (mapcar (function (lambda (item)
-                                     (vector (nth 1 item)
-                                             (nth 2 item)
-                                             t)))
-                         mime-edit-menu-list)))
-  )
-;;; end
+(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)
+       ))
 
 
 ;;; @ functions
@@ -679,40 +684,35 @@ format. The message tag looks like:
        --[[text/plain; charset=ISO-2022-JP][7bit]]
 
 The tag specifies the MIME content type, subtype, optional parameters
-and transfer encoding of the message following the tag. Messages
-without any tag are treated as `text/plain' by default. Charset and
+and transfer encoding of the message following the tag.  Messages
+without any tag are treated as `text/plain' by default.  Charset and
 transfer encoding are automatically defined unless explicitly
-specified. Binary messages such as audio and image are usually hidden.
-The messages in the tagged MIME format are automatically translated
-into a MIME compliant message when exiting this mode.
+specified.  Binary messages such as audio and image are usually
+hidden.  The messages in the tagged MIME format are automatically
+translated into a MIME compliant message when exiting this mode.
 
-Available charsets depend on Emacs version being used. The following
+Available charsets depend on Emacs version being used.  The following
 lists the available charsets of each emacs.
 
-EMACS 18:      US-ASCII is only available.
-NEmacs:                US-ASCII and ISO-2022-JP are available.
-EMACS 19:      US-ASCII and ISO-8859-1 (or other charset) are available.
-XEmacs 19:     US-ASCII and ISO-8859-1 (or other charset) are available.
-Mule:          US-ASCII, ISO-8859-* (except for ISO-8859-5), KOI8-R,
-               ISO-2022-JP, ISO-2022-JP-2, ISO-2022-KR, BIG5 and
-               ISO-2022-INT-1 are available.
+Without mule:  US-ASCII and ISO-8859-1 (or other charset) are available.
+With mule:     US-ASCII, ISO-8859-* (except for ISO-8859-5), KOI8-R,
+               ISO-2022-JP, ISO-2022-JP-2, EUC-KR, CN-GB-2312,
+               CN-BIG5 and ISO-2022-INT-1 are available.
 
 ISO-2022-JP-2 and ISO-2022-INT-1 charsets used in mule is expected to
-be used to represent multilingual text in intermixed manner. Any
+be used to represent multilingual text in intermixed manner.  Any
 languages that has no registered charset are represented as either
 ISO-2022-JP-2 or ISO-2022-INT-1 in mule.
 
-If you want to use non-ISO-8859-1 charset in EMACS 19 or XEmacs 19,
-please set variable `default-mime-charset'. This variable must be
-symbol of which name is a MIME charset.
+If you want to use non-ISO-8859-1 charset in Emacs 19 or XEmacs
+without mule, please set variable `default-mime-charset'.  This
+variable must be symbol of which name is a MIME charset.
 
 If you want to add more charsets in mule, please set variable
-`charsets-mime-charset-alist'. This variable must be alist of which
-key is list of leading-char/charset and value is symbol of MIME
-charset. (leading-char is a term of MULE 1.* and 2.*. charset is a
-term of XEmacs/mule, mule merged EMACS and MULE 3.*) If name of
-coding-system is different as MIME charset, please set variable
-`mime-charset-coding-system-alist'. This variable must be alist of
+`charsets-mime-charset-alist'.  This variable must be alist of which
+key is list of charset and value is symbol of MIME charset.  If name
+of coding-system is different as MIME charset, please set variable
+`mime-charset-coding-system-alist'.  This variable must be alist of
 which key is MIME charset and value is coding-system.
 
 Following commands are available in addition to major mode commands:
@@ -771,7 +771,7 @@ TABs at the beginning of the line are not a part of the message:
        --[[audio/basic][base64]]...audio encoded in base64 here...
 
 User customizable variables (not documented all of them):
- mime-prefix
+ mime-edit-prefix
     Specifies a key prefix for MIME minor mode commands.
 
  mime-ignore-preceding-spaces
@@ -808,34 +808,33 @@ 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)
+      )))
+
+;;;###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)
-    ;; Remember old key bindings.
-    (if running-xemacs
-       (use-local-map (or (current-local-map) (make-sparse-keymap)))
-      (make-local-variable 'mime-edit-mode-old-local-map)
-      (setq mime-edit-mode-old-local-map (current-local-map))
-      ;; Add MIME commands to current local map.
-      (use-local-map (copy-keymap (or (current-local-map)
-                                     (make-sparse-keymap))))
-      )
-    (if (not (lookup-key (current-local-map) mime-prefix))
-       (define-key (current-local-map) mime-prefix mime-edit-mime-map))
-
+    
     ;; Set transfer level into mode line
     ;;
     (setq mime-transfer-level-string
          (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)
     
@@ -853,8 +852,7 @@ 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.
@@ -871,12 +869,10 @@ just return to previous mode."
          (mime-edit-translate-buffer)))
     ;; Restore previous state.
     (setq mime-edit-mode-flag nil)
-    (cond (running-xemacs
-          (if (featurep 'menubar) 
-              (delete-menu-item (list mime-edit-menu-title))))
-         (t
-          (use-local-map mime-edit-mode-old-local-map)))
-    
+    (if (and running-xemacs
+            (featurep 'menubar))
+       (delete-menu-item (list mime-edit-menu-title))
+      )
     (end-of-invisible)
     (set-buffer-modified-p (buffer-modified-p))
     (run-hooks 'mime-edit-exit-hook)
@@ -1438,8 +1434,8 @@ Parameter must be '(PROMPT CHOICE1 (CHOISE2 ...))."
 
 (defvar mime-edit-translate-buffer-hook
   '(mime-edit-pgp-enclose-buffer
-    mime-edit-translate-header
-    mime-edit-translate-body))
+    mime-edit-translate-body
+    mime-edit-translate-header))
 
 (defun mime-edit-translate-header ()
   "Encode the message header into network representation."
@@ -1773,6 +1769,11 @@ Content-Transfer-Encoding: 7bit
       (let ((contype (car ret))                ;Content-Type
            (encoding (nth 1 ret))      ;Content-Transfer-Encoding
            )
+       ;; Insert X-Emacs field
+       (and mime-edit-insert-x-emacs-field
+            (or (mail-position-on-field "X-Emacs")
+                (insert mime-edit-x-emacs-value)
+                ))
        ;; Make primary MIME headers.
        (or (mail-position-on-field "Mime-Version")
            (insert mime-edit-mime-version-value))
@@ -2242,7 +2243,7 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
   (let* ((mime-edit-draft-file-name 
          (or (buffer-file-name)
              (make-temp-name
-              (expand-file-name "mime-draft" mime/tmp-dir))))
+              (expand-file-name "mime-draft" mime-temp-directory))))
         (separator mail-header-separator)
         (id (concat "\""
                     (replace-space-with-underline (current-time-string))
@@ -2344,6 +2345,8 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
 ;;; @ preview message
 ;;;
 
+(defvar mime-edit-buffer nil) ; buffer local variable
+
 (defun mime-edit-preview-message ()
   "preview editing MIME message. [mime-edit.el]"
   (interactive)
@@ -2363,11 +2366,11 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
       (switch-to-buffer buf)
       )
     (insert str)
-    (setq major-mode 'mime/temporary-message-mode)
+    (setq major-mode 'mime-temp-message-mode)
     (make-local-variable 'mail-header-separator)
     (setq mail-header-separator separator)
-    (make-local-variable 'mime/editing-buffer)
-    (setq mime/editing-buffer the-buf)
+    (make-local-variable 'mime-edit-buffer)
+    (setq mime-edit-buffer the-buf)
     
     (run-hooks 'mime-edit-translate-hook)
     (mime-edit-translate-buffer)
@@ -2384,78 +2387,27 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
        buf)
     (mime-view-kill-buffer)
     (set-buffer temp)
-    (setq buf mime/editing-buffer)
+    (setq buf mime-edit-buffer)
     (kill-buffer temp)
     (switch-to-buffer buf)
     ))
 
 (set-alist 'mime-view-quitting-method-alist
-          'mime/temporary-message-mode
+          'mime-temp-message-mode
           (function mime-edit-quitting-method)
           )
 
 
-;;; @ draft preview
-;;; 
-;; by "OKABE Yasuo <okabe@kudpc.kyoto-u.ac.jp>
-;;      Mon, 10 Apr 1995 20:03:07 +0900
-
-(defvar mime-edit-draft-header-separator-alist
-  '((news-reply-mode . mail-header-separator)
-    (mh-letter-mode . mail-header-separator)
-    ))
-
-(defvar mime::article/draft-header-separator nil)
-
-(defun mime-edit-draft-preview ()
-  (interactive)
-  (let ((sep (cdr (assq major-mode mime-edit-draft-header-separator-alist))))
-    (or (stringp sep) (setq sep (eval sep)))
-    (make-variable-buffer-local 'mime::article/draft-header-separator)
-    (goto-char (point-min))
-    (re-search-forward
-     (concat "^\\(" (regexp-quote sep) "\\)?$"))
-    (setq mime::article/draft-header-separator
-         (buffer-substring (match-beginning 0) (match-end 0)))
-    (replace-match "")
-    (mime-view-mode (current-buffer))
-    (pop-to-buffer (current-buffer))
-    ))
-
-(defun mime-viewer::quitting-method/draft-preview ()
-  (let ((mother mime::preview/mother-buffer))
-    (save-excursion
-      (switch-to-buffer mother)
-      (goto-char (point-min))
-      (if (and
-          (re-search-forward
-           (concat "^\\("
-                   (regexp-quote mime::article/draft-header-separator)
-                   "\\)?$") nil t)
-          (bolp))
-         (progn
-           (insert mime::article/draft-header-separator)
-           (set-buffer-modified-p (buffer-modified-p))
-           )))
-    (mime-view-kill-buffer)
-    (pop-to-buffer mother)
-    ))
-
-(set-alist 'mime-view-quitting-method-alist
-          'mh-letter-mode
-          (function mime-viewer::quitting-method/draft-preview)
-          )
-
-(set-alist 'mime-view-quitting-method-alist
-          'news-reply-mode
-          (function mime-viewer::quitting-method/draft-preview)
-          )
-
-
 ;;; @ 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)))
@@ -2504,7 +2456,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))
                            ))))
                    ))
@@ -2563,7 +2515,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))
@@ -2587,36 +2539,37 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
                      (concat 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)
       ))