This commit was generated by cvs2svn to compensate for changes in r494,
[elisp/tm.git] / tm-edit.el
index 6e9724c..03587b0 100644 (file)
@@ -6,7 +6,7 @@
 ;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;; Maintainer: MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;; Created: 1994/08/21 renamed from mime.el
-;; Version: $Revision: 7.92 $
+;; Version: $Revision: 7.98 $
 ;; Keywords: mail, news, MIME, multimedia, multilingual
 
 ;; This file is part of tm (Tools for MIME).
 ;;; Commentary:
 
 ;; This is an Emacs minor mode for editing Internet multimedia
-;; messages formatted in MIME (RFC 1521 and RFC 1522). All messages in
-;; this mode are composed in the tagged MIME format, that are
-;; described in the following examples. The messages composed in the
-;; tagged MIME format are automatically translated into a MIME
-;; compliant message when exiting the mode.
+;; messages formatted in MIME (RFC 2045, 2046, 2047, 2048 and 2049).
+;; All messages in this mode are composed in the tagged MIME format,
+;; that are described in the following examples.  The messages
+;; 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
+;; 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] or `ISO-2022-INT-1'. Mule is required
+;; `ISO-2022-JP-2' [RFC 1554] or `ISO-2022-INT-1'.  Mule is required
 ;; for reading the such messages.
 
 ;; This MIME composer can work with Mail mode, mh-e letter Mode, and
 (require 'sendmail)
 (require 'mail-utils)
 (require 'mel)
-(require 'tl-822)
 (require 'tl-list)
 (require 'tm-view)
 (require 'tm-ew-e)
 ;;;
 
 (defconst mime-editor/RCS-ID
-  "$Id: tm-edit.el,v 7.92 1996/10/24 08:25:47 morioka Exp $")
+  "$Id: tm-edit.el,v 7.98 1996/12/23 14:49:34 morioka Exp $")
 
 (defconst mime-editor/version (get-version-string mime-editor/RCS-ID))
 
@@ -405,11 +404,14 @@ Each elements are regexp of field-name. [tm-edit.el]")
 (defvar mime-editor/split-message t
   "*Split large message if it is non-nil. [tm-edit.el]")
 
-(defvar mime-editor/message-default-max-length 1000
-  "*Default maximum size of a message. [tm-edit.el]")
+(defvar mime-editor/message-default-max-lines 1000
+  "*Default maximum lines of a message. [tm-edit.el]")
 
-(defvar mime-editor/message-max-length-alist
-  '((news-reply-mode . 500)))
+(defvar mime-editor/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-editor/message-default-max-lines' is used. [tm-edit.el]")
 
 (defconst mime-editor/split-ignored-field-regexp
   "\\(^Content-\\|^Subject:\\|^Mime-Version:\\)")
@@ -425,15 +427,21 @@ Each elements are regexp of field-name. [tm-edit.el]")
 ;;; @@ about PGP
 ;;;
 
-(defvar mime-editor/signing-type nil
+(defvar mime-editor/signing-type 'pgp-elkins
   "*PGP signing type (pgp-elkins, pgp-kazu or nil). [tm-edit.el]")
 
-(defvar mime-editor/encrypting-type nil
+(defvar mime-editor/encrypting-type 'pgp-elkins
   "*PGP encrypting type (pgp-elkins, pgp-kazu or nil). [tm-edit.el]")
 
-(if (or mime-editor/signing-type mime-editor/encrypting-type)
-    (require 'mailcrypt)
-  )
+(defvar mime-editor/pgp-sign-function 'tm:mc-pgp-sign-region)
+(defvar mime-editor/pgp-encrypt-function 'tm:mc-pgp-encrypt-region)
+(defvar mime-editor/traditional-pgp-sign-function 'mc-pgp-sign-region)
+(defvar mime-editor/pgp-insert-public-key-function 'mc-insert-public-key)
+
+(autoload mime-editor/pgp-sign-function "tm-edit-mc")
+(autoload mime-editor/pgp-encrypt-function "tm-edit-mc")
+(autoload mime-editor/traditional-pgp-sign-function "mc-pgp")
+(autoload mime-editor/pgp-insert-public-key-function "mc-toplev")
 
 
 ;;; @@ about tag
@@ -875,32 +883,24 @@ Charset is automatically obtained from the `mime/lc-charset-alist'."
              (enriched-mode nil)
            ))))))
 
-(defun mime-editor/insert-file (file)
+(defun mime-editor/insert-file (file &optional verbose)
   "Insert a message from a file."
-  (interactive "fInsert file as MIME message: ")
+  (interactive "fInsert file as MIME message: \nP")
   (let*  ((guess (mime-find-file-type file))
-         (pritype (nth 0 guess))
+         (type (nth 0 guess))
          (subtype (nth 1 guess))
          (parameters (nth 2 guess))
-         (default (nth 3 guess))       ;Guess encoding from its file name.
+         (encoding (nth 3 guess))
          (disposition-type (nth 4 guess))
          (disposition-params (nth 5 guess))
-         (encoding
-          (if (not (interactive-p))
-              default
-            (completing-read
-             (concat "What transfer encoding"
-                     (if default
-                         (concat " (default "
-                                 (if (string-equal default "")
-                                     "\"\""
-                                   default)
-                                 ")"
-                                 ))
-                     ": ")
-             mime-file-encoding-method-alist nil t nil))))
-    (if (string-equal encoding "")
-       (setq encoding default))
+         )
+    (if verbose
+       (setq type    (mime-prompt-for-type type)
+             subtype (mime-prompt-for-subtype type subtype)
+             ))
+    (if (interactive-p)
+       (setq encoding (mime-prompt-for-encoding encoding))
+      )
     (if (or (consp parameters) (stringp disposition-type))
        (let ((rest parameters) cell attribute value)
          (setq parameters "")
@@ -935,7 +935,7 @@ Charset is automatically obtained from the `mime/lc-charset-alist'."
                  )
                ))
          ))
-    (mime-editor/insert-tag pritype subtype parameters)
+    (mime-editor/insert-tag type subtype parameters)
     (mime-editor/insert-binary-file file encoding)
     ))
 
@@ -1288,7 +1288,7 @@ Nil if no such parameter."
     guess
     ))
 
-(defun mime-prompt-for-type ()
+(defun mime-prompt-for-type (&optional default)
   "Ask for Content-type."
   (let ((type ""))
     ;; Repeat until primary content type is specified.
@@ -1298,7 +1298,7 @@ Nil if no such parameter."
                             mime-content-types
                             nil
                             'require-match ;Type must be specified.
-                            nil
+                            default
                             ))
       (if (string-equal type "")
          (progn
@@ -1307,19 +1307,22 @@ Nil if no such parameter."
            (sit-for 1)
            ))
       )
-    type
-    ))
-
-(defun mime-prompt-for-subtype (pritype)
-  "Ask for Content-type subtype of Content-Type PRITYPE."
-  (let* ((default (car (car (cdr (assoc pritype mime-content-types)))))
-        (answer
+    type))
+
+(defun mime-prompt-for-subtype (type &optional default)
+  "Ask for subtype of media-type TYPE."
+  (let ((subtypes (cdr (assoc type mime-content-types))))
+    (or (and default
+            (assoc default subtypes))
+       (setq default (car (car subtypes)))
+       ))
+  (let* ((answer
          (completing-read
           (if default
               (concat
                "What content subtype: (default " default ") ")
             "What content subtype: ")
-          (cdr (assoc pritype mime-content-types))
+          (cdr (assoc type mime-content-types))
           nil
           'require-match               ;Subtype must be specified.
           nil
@@ -1382,17 +1385,24 @@ Parameter must be '(PROMPT CHOICE1 (CHOISE2 ...))."
          (mime-prompt-for-parameters-1 (cdr (assoc answer (cdr parameter)))))
     ))
 
-(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,
-while if FLAG is `\\^M' (control-M) the text is hidden."
-  (let ((buffer-read-only nil)         ;Okay even if write protected.
-       (modp (buffer-modified-p)))
-    (unwind-protect
-        (subst-char-in-region from to
-                             (if (= flag ?\n) ?\^M ?\n)
-                             flag t)
-      (set-buffer-modified-p modp))))
+(defun mime-prompt-for-encoding (default)
+  "Ask for Content-Transfer-Encoding. [tm-edit.el]"
+  (let ((ret
+        (completing-read
+         (concat "What transfer encoding"
+                 (if default
+                     (concat " (default "
+                             (if (string-equal default "")
+                                 "\"\""
+                               default)
+                             ")"
+                             ))
+                 ": ")
+         mime-file-encoding-method-alist nil t nil)
+        ))
+    (if (string= ret "")
+       default
+      ret)))
 
 \f
 ;;; @ Translate the tagged MIME messages into a MIME compliant message.
@@ -1522,129 +1532,6 @@ while if FLAG is `\\^M' (control-M) the text is hidden."
          (replace-match (concat "-" (substring tag 2)))
          )))))
 
-(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))
-      )))
-
-(defun tm:mc-process-region
-  (beg end passwd program args parser &optional buffer boundary)
-  (let ((obuf (current-buffer))
-       (process-connection-type nil)
-       mybuf result rgn proc)
-    (unwind-protect
-       (progn
-         (setq mybuf (or buffer (generate-new-buffer " *mailcrypt temp")))
-         (set-buffer mybuf)
-         (erase-buffer)
-         (set-buffer obuf)
-         (buffer-disable-undo mybuf)
-         (setq proc
-               (apply 'start-process "*PGP*" mybuf program args))
-         (if passwd
-             (progn
-               (process-send-string proc (concat passwd "\n"))
-               (or mc-passwd-timeout (mc-deactivate-passwd t))))
-         (process-send-region proc beg end)
-         (process-send-eof proc)
-         (while (eq 'run (process-status proc))
-           (accept-process-output proc 5))
-         (setq result (process-exit-status proc))
-         ;; Hack to force a status_notify() in Emacs 19.29
-         (delete-process proc)
-         (set-buffer mybuf)
-         (goto-char (point-max))
-         (if (re-search-backward "\nProcess \\*PGP.*\n\\'" nil t)
-             (delete-region (match-beginning 0) (match-end 0)))
-         (goto-char (point-min))
-         ;; CRNL -> NL
-         (while (search-forward "\r\n" nil t)
-           (replace-match "\n"))
-         ;; Hurm.  FIXME; must get better result codes.
-         (if (stringp result)
-             (error "%s exited abnormally: '%s'" program result)
-           (setq rgn (funcall parser result))
-           ;; If the parser found something, migrate it
-           (if (consp rgn)
-               (progn
-                 (set-buffer obuf)
-                 (if boundary
-                     (save-restriction
-                       (narrow-to-region beg end)
-                       (goto-char beg)
-                       (insert (format "--%s\n" boundary))
-                       (goto-char (point-max))
-                       (insert (format "\n--%s
-Content-Type: application/pgp-signature
-Content-Transfer-Encoding: 7bit
-
-" boundary))
-                       (insert-buffer-substring mybuf (car rgn) (cdr rgn))
-                       (goto-char (point-max))
-                       (insert (format "\n--%s--\n" boundary))
-                       )
-                   (delete-region beg end)
-                   (goto-char beg)
-                   (insert-buffer-substring mybuf (car rgn) (cdr rgn))
-                   )
-                 (set-buffer mybuf)
-                 (delete-region (car rgn) (cdr rgn)))))
-         ;; Return nil on failure and exit code on success
-         (if rgn result))
-      ;; Cleanup even on nonlocal exit
-      (if (and proc (eq 'run (process-status proc)))
-         (interrupt-process proc))
-      (set-buffer obuf)
-      (or buffer (null mybuf) (kill-buffer mybuf)))))
-
-(defun tm:mc-pgp-sign-region (start end &optional id unclear boundary)
-  (if (not (boundp 'mc-pgp-user-id))
-      (load "mc-pgp")
-    )
-  (let ((process-environment process-environment)
-       (buffer (get-buffer-create mc-buffer-name))
-       passwd args key
-       (parser (function mc-pgp-generic-parser))
-       (pgp-path mc-pgp-path)
-       )
-    (setq key (mc-pgp-lookup-key (or id mc-pgp-user-id)))
-    (setq passwd
-         (mc-activate-passwd
-          (cdr key)
-          (format "PGP passphrase for %s (%s): " (car key) (cdr key))))
-    (setenv "PGPPASSFD" "0")
-    (setq args
-         (cons
-          (if boundary
-              "-fbast"
-            "-fast")
-          (list "+verbose=1" "+language=en"
-                (format "+clearsig=%s" (if unclear "off" "on"))
-                "+batchmode" "-u" (cdr key))))
-    (if mc-pgp-comment
-       (setq args (cons (format "+comment=%s" mc-pgp-comment) args))
-      )
-    (message "Signing as %s ..." (car key))
-    (if (tm:mc-process-region
-        start end passwd pgp-path args parser buffer boundary)
-       (progn
-         (if boundary
-             (progn
-               (goto-char (point-min))
-               (insert
-                (format "\
---[[multipart/signed; protocol=\"application/pgp-signature\";
- boundary=\"%s\"; micalg=pgp-md5][7bit]]\n" boundary))
-               ))
-         (message "Signing as %s ... Done." (car key))
-         t)
-      nil)))
-
 (defun mime-editor/sign-pgp-elkins (beg end boundary)
   (save-excursion
     (save-restriction
@@ -1662,8 +1549,8 @@ Content-Transfer-Encoding: 7bit
            (insert (format "Content-Transfer-Encoding: %s\n" encoding))
          )
        (insert "\n")
-       (or (tm:mc-pgp-sign-region (point-min)(point-max)
-                                  nil nil pgp-boundary)
+       (or (funcall mime-editor/pgp-sign-function
+                    (point-min)(point-max) nil nil pgp-boundary)
            (throw 'mime-editor/error 'pgp-error)
            )
        ))))
@@ -1726,14 +1613,10 @@ Content-Transfer-Encoding: 7bit
              (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)
-                ))
+         (or (funcall mime-editor/pgp-encrypt-function
+                      recipients (point-min) (point-max) from)
              (throw 'mime-editor/error 'pgp-error)
-           )
+             )
          (goto-char beg)
          (insert (format "--[[multipart/encrypted;
  boundary=\"%s\";
@@ -1766,7 +1649,9 @@ Content-Transfer-Encoding: 7bit
            (insert (format "Content-Transfer-Encoding: %s\n" encoding))
          )
        (insert "\n")
-       (or (as-binary-process (mc-pgp-sign-region beg (point-max)))
+       (or (as-binary-process
+            (funcall mime-editor/traditional-pgp-sign-function
+                     beg (point-max)))
            (throw 'mime-editor/error 'pgp-error)
            )
        (goto-char beg)
@@ -1799,9 +1684,8 @@ Content-Transfer-Encoding: 7bit
            )
          (insert "\n")
          (or (as-binary-process
-              (mc-pgp-encrypt-region
-               (mc-split "\\([ \t\n]*,[ \t\n]*\\)+" recipients)
-               beg (point-max))
+              (funcall mime-editor/pgp-encrypt-function
+                       recipients beg (point-max) nil 'maybe)
               )
              (throw 'mime-editor/error 'pgp-error)
              )
@@ -2181,7 +2065,7 @@ and insert data encoded as ENCODING. [tm-edit.el]"
   (interactive "P")
   (mime-editor/insert-tag "application" "pgp-keys")
   (mime-editor/define-encoding "7bit")
-  (mc-insert-public-key)
+  (funcall mime-editor/pgp-insert-public-key-function)
   )
 
 
@@ -2316,8 +2200,8 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
       )
   (or mime-editor/message-max-length
       (setq mime-editor/message-max-length
-           (or (cdr (assq major-mode mime-editor/message-max-length-alist))
-               mime-editor/message-default-max-length))
+           (or (cdr (assq major-mode mime-editor/message-max-lines-alist))
+               mime-editor/message-default-max-lines))
       )
   (let* ((mime-editor/draft-file-name 
          (or (buffer-file-name)
@@ -2411,8 +2295,8 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
   (interactive)
   (run-hooks 'mime-editor/before-send-hook)
   (let ((mime-editor/message-max-length
-        (or (cdr (assq major-mode mime-editor/message-max-length-alist))
-            mime-editor/message-default-max-length))
+        (or (cdr (assq major-mode mime-editor/message-max-lines-alist))
+            mime-editor/message-default-max-lines))
        (lines (count-lines (point-min) (point-max)))
        )
     (if (and (> lines mime-editor/message-max-length)
@@ -2596,18 +2480,27 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
             (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 ""))
+                     (let ((bytes (+ 14 (length ctype))))
+                       (mapconcat (function
+                                   (lambda (attr)
+                                     (if (string-equal (car attr) "charset")
+                                         (progn
+                                           (setq charset (cdr attr))
+                                           "")
+                                       (let* ((str
+                                               (concat (car attr)
+                                                       "=" (cdr attr))
+                                               )
+                                              (bs (length str))
+                                              )
+                                         (setq bytes (+ bytes bs 2))
+                                         (if (< bytes 76)
+                                             (concat "; " str)
+                                           (setq bytes (+ bs 1))
+                                           (concat ";\n " str)
+                                           )
+                                         ))))
+                                  params "")))
                     encoding
                     encoded)
                (save-excursion