X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=tm-edit.el;h=a1061a58d9ef87b03cbf1d679648095a34a5cc78;hb=cd47eed235f4258380f6d9b401c2fb1fc884931c;hp=332d0b8a2a2227b2094810f91b27fa98d4dd765f;hpb=408b03e1ab2d39df83ec2a80b3bc0591ba564c8e;p=elisp%2Ftm.git diff --git a/tm-edit.el b/tm-edit.el index 332d0b8..a1061a5 100644 --- a/tm-edit.el +++ b/tm-edit.el @@ -8,7 +8,7 @@ ;;; MORIOKA Tomohiko ;;; Maintainer: MORIOKA Tomohiko ;;; Created: 1994/08/21 renamed from mime.el -;;; Version: $Revision: 7.44 $ +;;; Version: $Revision: 7.72 $ ;;; Keywords: mail, news, MIME, multimedia, multilingual ;;; ;;; This file is part of tm (Tools for MIME). @@ -122,10 +122,13 @@ ;;; (defconst mime-editor/RCS-ID - "$Id: tm-edit.el,v 7.44 1996/02/23 16:16:30 morioka Exp $") + "$Id: tm-edit.el,v 7.72 1996/07/15 08:19:01 morioka Exp $") (defconst mime-editor/version (get-version-string mime-editor/RCS-ID)) +(defconst mime-editor/version-name + (concat "tm-edit " mime-editor/version)) + ;;; @ variables ;;; @@ -133,9 +136,6 @@ (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 +149,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 +158,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 +337,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 +353,40 @@ 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) + +(defun mime-editor/make-charset-default-encoding-alist (transfer-level) + (mapcar (function + (lambda (charset-type) + (let ((charset (car charset-type)) + (type (nth 1 charset-type)) + (encoding (nth 2 charset-type)) + ) + (if (<= type transfer-level) + (cons charset (mime/encoding-name type)) + (cons charset encoding) + )))) + mime-charset-type-list)) + +(defvar mime-editor/charset-default-encoding-alist + (mime-editor/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 +417,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 +441,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) @@ -468,12 +462,15 @@ Each elements are regexp of field-name. [tm-edit.el]") ;;; (defconst mime-editor/single-part-tag-regexp - "^--[[][[]\\([^]]*\\)]\\([[]\\([^]]*\\)]\\|\\)]" + "--[[][[]\\([^]]*\\)]\\([[]\\([^]]*\\)]\\|\\)]" "*Regexp of MIME tag in the form of [[CONTENT-TYPE][ENCODING]].") -(defconst mime-editor/multipart-beginning-regexp "^--<<\\([^<>]+\\)>>-{\n") +(defconst mime-editor/quoted-single-part-tag-regexp + (concat "- " (substring mime-editor/single-part-tag-regexp 1))) + +(defconst mime-editor/multipart-beginning-regexp "--<<\\([^<>]+\\)>>-{\n") -(defconst mime-editor/multipart-end-regexp "^--}-<<\\([^<>]+\\)>>\n") +(defconst mime-editor/multipart-end-regexp "--}-<<\\([^<>]+\\)>>\n") (defconst mime-editor/beginning-tag-regexp (regexp-or mime-editor/single-part-tag-regexp @@ -517,7 +514,7 @@ Each elements are regexp of field-name. [tm-edit.el]") Tspecials means any character that matches with it in header must be quoted.") (defconst mime-editor/mime-version-value - (format "1.0 (generated by tm-edit %s)" mime-editor/version) + (concat "1.0 (generated by " mime-editor/version-name ")") "MIME version number.") (defconst mime-editor/mime-map (make-sparse-keymap) @@ -529,8 +526,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)) @@ -551,6 +546,7 @@ Tspecials means any character that matches with it in header must be quoted.") (define-key keymap "d" 'mime-editor/enclose-digest-region) (define-key keymap "s" 'mime-editor/enclose-signed-region) (define-key keymap "e" 'mime-editor/enclose-encrypted-region) + (define-key keymap "q" 'mime-editor/enclose-quote-region) (define-key keymap "\C-p" 'mime-editor/preview-message) (define-key keymap "\C-z" 'mime-editor/exit) (define-key keymap "?" 'mime-editor/help) @@ -558,6 +554,34 @@ Tspecials means any character that matches with it in header must be quoted.") (mime-editor/define-keymap mime-editor/mime-map) +(defun mime-editor/toggle-mode () + (interactive) + (if mime/editor-mode-flag + (mime-editor/exit 'nomime) + (mime/editor-mode) + )) + +(cond (running-xemacs + (defconst mime-editor/minor-mime-map nil "Keymap for MIME commands.") + (or mime-editor/minor-mime-map + (progn + (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) + )) + (add-minor-mode 'mime/editor-mode-flag + '((" MIME-Edit " mime-editor/transfer-level-string)) + mime-editor/minor-mime-map + nil + 'mime-editor/toggle-mode) + ) + (t + (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 @@ -577,11 +601,13 @@ Tspecials means any character that matches with it in header must be quoted.") (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) + (quote "Verbatim region" mime-editor/enclose-quote-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.") @@ -600,7 +626,7 @@ Tspecials means any character that matches with it in header must be quoted.") (reverse mime-editor/menu-list) )) -;;; modified by Pekka Marjola +;;; modified by Pekka Marjola ;;; 1995/9/5 (c.f. [tm-en:69]) (defun mime-editor/define-menu-for-xemacs () "Define menu for Emacs 19." @@ -619,8 +645,7 @@ Tspecials means any character that matches with it in header must be quoted.") ;;; modified by Steven L. Baur ;;; 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) @@ -712,10 +737,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. @@ -729,10 +750,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 @@ -756,22 +773,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. - (if (string-match "XEmacs\\|Lucid" emacs-version) + (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)))) + (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 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 - ;; 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,11 +834,7 @@ just return to previous mode." (mime-editor/translate-buffer))) ;; Restore previous state. (setq mime/editor-mode-flag nil) - (cond ((string-match "XEmacs\\|Lucid" emacs-version) - ;; mime-prefix only defined if binding was nil - (if (eq (lookup-key (current-local-map) mime-prefix) - mime-editor/mime-map) - (define-key (current-local-map) mime-prefix nil)) + (cond (running-xemacs (delete-menu-item (list mime-editor/menu-title))) (t (use-local-map mime/editor-mode-old-local-map))) @@ -946,32 +964,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) + )) ;; Insert a new tag around a point. @@ -983,7 +986,7 @@ If nothing is inserted, return nil." (let ((oldtag nil) (newtag nil) (current (point)) - exist-prev-tag exist-next-tag) + ) (setq pritype (or pritype (mime-prompt-for-type))) @@ -999,13 +1002,7 @@ If nothing is inserted, return nil." (setq oldtag (save-excursion (if (mime-editor/goto-tag) - (progn - (if (eq current (match-beginning 0)) - (setq exist-next-tag t) - (setq exist-prev-tag t) - ) - (buffer-substring (match-beginning 0) (match-end 0)) - ) + (buffer-substring (match-beginning 0) (match-end 0)) ;; Assume content type is 'text/plan'. (mime-make-tag "text" "plain") ))) @@ -1014,15 +1011,6 @@ If nothing is inserted, return nil." (not (mime-test-content-type (mime-editor/get-contype oldtag) "text"))) (setq oldtag nil)) - (cond (exist-prev-tag (insert "\n")) - (exist-next-tag (save-excursion - (insert "\n") - ))) - (if (not (bolp)) - (if exist-prev-tag - (forward-line 1) - (insert "\n") - )) ;; Make a new tag. (if (or (not oldtag) ;Not text (or mime-ignore-same-text-tag @@ -1093,11 +1081,13 @@ 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) - (goto-char (point-max))) + (invisible-region (point-min) (point-max)) + (goto-char (point-max)) + ) )) ;; Define encoding even if it is 7bit. (if (stringp encoding) @@ -1116,16 +1106,13 @@ Optional argument ENCODING specifies an encoding method such as base64." t ;; At first, go to the end. (cond ((re-search-forward mime-editor/beginning-tag-regexp nil t) - (goto-char (match-beginning 0)) ;For multiline tag - (forward-line -1) - (end-of-line) + (goto-char (1- (match-beginning 0))) ;For multiline tag ) (t (goto-char (point-max)) )) ;; Then search for the beginning. (re-search-backward mime-editor/end-tag-regexp nil t) - (beginning-of-line) (or (looking-at mime-editor/beginning-tag-regexp) ;; Restore previous point. (progn @@ -1159,20 +1146,17 @@ Optional argument ENCODING specifies an encoding method such as base64." (defun mime-editor/content-end () "Return the point of the end of content." (save-excursion - (let ((beg (save-excursion - (beginning-of-line) (point)))) + (let ((beg (point))) (if (mime-editor/goto-tag) (let ((top (point))) (goto-char (match-end 0)) - (if (and (= beg top) ;Must be on the same line. - (= (following-char) ?\^M)) - (progn - (end-of-line) - (point)) + (if (invisible-p (point)) + (next-visible-point (point)) ;; Move to the end of this text. (if (re-search-forward mime-editor/tag-regexp nil 'move) ;; Don't forget a multiline tag. - (goto-char (match-beginning 0))) + (goto-char (match-beginning 0)) + ) (point) )) ;; Assume the message begins with text/plain. @@ -1190,10 +1174,12 @@ Optional argument ENCODING specifies an encoding method such as base64." (let ((tag (buffer-substring (match-beginning 0) (match-end 0)))) (delete-region (match-beginning 0) (match-end 0)) (insert - (mime-create-tag (mime-set-parameter - (mime-editor/get-contype tag) "charset" charset) - (mime-editor/get-encoding tag)))) - ))) + (mime-create-tag + (mime-editor/set-parameter + (mime-editor/get-contype tag) + "charset" (upcase (symbol-name charset))) + (mime-editor/get-encoding tag))) + )))) (defun mime-editor/define-encoding (encoding) "Set encoding of current tag to ENCODING." @@ -1206,7 +1192,7 @@ Optional argument ENCODING specifies an encoding method such as base64." (defun mime-editor/choose-charset () "Choose charset of a text following current point." - (mime/find-charset-region (point) (mime-editor/content-end)) + (detect-mime-charset-region (point) (mime-editor/content-end)) ) (defun mime-make-text-tag (&optional subtype) @@ -1264,19 +1250,27 @@ Nil if no such parameter." nil ;No such parameter )) -(defun mime-set-parameter (contype parameter value) +(defun mime-editor/set-parameter (contype parameter value) "For given CONTYPE set PARAMETER to VALUE." - (if (string-match - (concat - ";[ \t\n]*\\(" - (regexp-quote parameter) - "[ \t\n]*=[ \t\n]*\\([^\" \t\n;]*\\|\"[^\"]*\"\\)\\)[ \t\n]*\\(;\\|$\\)") - contype) - ;; Change value - (concat (substring contype 0 (match-beginning 1)) - parameter "=" value - (substring contype (match-end 1))) - (concat contype "; " parameter "=" value))) + (let (ctype opt-fields) + (if (string-match "\n[^ \t\n\r]+:" contype) + (setq ctype (substring contype 0 (match-beginning 0)) + opt-fields (substring contype (match-beginning 0))) + (setq ctype contype) + ) + (if (string-match + (concat + ";[ \t\n]*\\(" + (regexp-quote parameter) + "[ \t\n]*=[ \t\n]*\\([^\" \t\n;]*\\|\"[^\"]*\"\\)\\)[ \t\n]*\\(;\\|$\\)") + ctype) + ;; Change value + (concat (substring ctype 0 (match-beginning 1)) + parameter "=" value + (substring contype (match-end 1)) + opt-fields) + (concat ctype "; " parameter "=" value opt-fields) + ))) (defun mime-strip-parameters (contype) "Return primary content-type and subtype without parameters for CONTYPE." @@ -1399,30 +1393,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, @@ -1439,14 +1409,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-editor/pgp-enclose-buffer) - (mime/encode-message-header) - (mime-editor/translate-body) + (run-hooks 'mime-editor/translate-buffer-hook) )) (progn (undo) @@ -1460,7 +1433,7 @@ while if FLAG is `\\^M' (control-M) the text is hidden." (be (match-end 0)) (type (buffer-substring (match-beginning 1)(match-end 1))) end-exp eb ee) - (setq end-exp (format "^--}-<<%s>>\n" type)) + (setq end-exp (format "--}-<<%s>>\n" type)) (widen) (if (re-search-forward end-exp nil t) (progn @@ -1478,7 +1451,6 @@ while if FLAG is `\\^M' (control-M) the text is hidden." (mime-editor/find-inmost) ) (widen) - ;;(delete-region eb ee) (list type bb be eb) )))) @@ -1500,26 +1472,27 @@ while if FLAG is `\\^M' (control-M) the text is hidden." (end (match-end 0)) ) (delete-region beg end) - (if (and (not (looking-at mime-editor/single-part-tag-regexp)) - (not (eobp))) + (or (looking-at mime-editor/beginning-tag-regexp) + (eobp) (insert (concat (mime-make-text-tag) "\n")) - ))) - (cond ((string= type "signed") + ))) + (cond ((string-equal type "quote") + (mime-editor/enquote-region bb eb) + ) + ((string-equal type "signed") (cond ((eq mime-editor/signing-type 'pgp-elkins) (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) - ) - )) - ((string= type "encrypted") - (cond ((eq mime-editor/signing-type 'pgp-elkins) + (mime-editor/sign-pgp-kazu bb eb boundary) + )) + ) + ((string-equal type "encrypted") + (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 @@ -1533,14 +1506,37 @@ while if FLAG is `\\^M' (control-M) the text is hidden." )) boundary)))) +(defun mime-editor/enquote-region (beg end) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char beg) + (while (re-search-forward mime-editor/single-part-tag-regexp nil t) + (let ((tag (buffer-substring (match-beginning 0)(match-end 0)))) + (replace-match (concat "- " (substring tag 1))) + ))))) + +(defun mime-editor/dequote-region (beg end) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char beg) + (while (re-search-forward + mime-editor/quoted-single-part-tag-regexp nil t) + (let ((tag (buffer-substring (match-beginning 0)(match-end 0)))) + (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)) ))) -(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)) @@ -1677,8 +1673,6 @@ Content-Transfer-Encoding: 7bit ) )))) -(autoload 'mc-pgp-encrypt-region "mc-pgp") - (defun mime-editor/encrypt-pgp-elkins (beg end boundary) (save-excursion (save-restriction @@ -1742,7 +1736,7 @@ Content-Transfer-Encoding: 7bit (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) @@ -1758,26 +1752,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) @@ -1813,6 +1847,7 @@ Content-Transfer-Encoding: 7bit beg end (format "%s-%d" boundary i))) )) + (mime-editor/dequote-region (point-min)(point-max)) (let ((contype (car ret)) ;Content-Type (encoding (nth 1 ret)) ;Content-Transfer-Encoding ) @@ -1836,6 +1871,25 @@ Content-Transfer-Encoding: 7bit (insert encoding))) )))) +(defun mime-editor/translate-single-part-tag (&optional prefix) + (if (re-search-forward mime-editor/single-part-tag-regexp nil t) + (let* ((beg (match-beginning 0)) + (end (match-end 0)) + (tag (buffer-substring beg end)) + ) + (delete-region beg end) + (setq contype (mime-editor/get-contype tag)) + (setq encoding (mime-editor/get-encoding tag)) + (insert (concat prefix "--" boundary "\n")) + (save-restriction + (narrow-to-region (point)(point)) + (insert "Content-Type: " contype "\n") + (if encoding + (insert "Content-Transfer-Encoding: " encoding "\n")) + (mime/encode-message-header) + ) + t))) + (defun mime-editor/translate-region (beg end &optional boundary multipart) (if (null boundary) (setq boundary @@ -1857,46 +1911,36 @@ Content-Transfer-Encoding: 7bit (while (re-search-forward mime-editor/single-part-tag-regexp nil t) (setq nparts (1+ nparts))) ;; Begin translation. - (cond ((and (<= nparts 1)(not multipart)) - ;; It's a singular message. - (goto-char (point-min)) - (while (re-search-forward - mime-editor/single-part-tag-regexp nil t) - (setq tag - (buffer-substring (match-beginning 0) (match-end 0))) - (delete-region (match-beginning 0) (1+ (match-end 0))) - (setq contype (mime-editor/get-contype tag)) - (setq encoding (mime-editor/get-encoding tag)) - )) - (t - ;; It's a multipart message. - (goto-char (point-min)) - (while (re-search-forward - mime-editor/single-part-tag-regexp nil t) - (setq tag - (buffer-substring (match-beginning 0) (match-end 0))) - (delete-region (match-beginning 0) (match-end 0)) - (setq contype (mime-editor/get-contype tag)) - (setq encoding (mime-editor/get-encoding tag)) - (insert "--" boundary "\n") - (insert "Content-Type: " contype "\n") - (if encoding - (insert "Content-Transfer-Encoding: " encoding "\n")) - ) - ;; Define Content-Type as "multipart/mixed". - (setq contype - (concat "multipart/mixed;\n boundary=\"" boundary "\"")) - ;; Content-Transfer-Encoding must be "7bit". - ;; The following encoding can be `nil', but is - ;; specified as is since there is no way that a user - ;; specifies it. - (setq encoding "7bit") - ;; Insert the trailer. - (goto-char (point-max)) - (if multipart - (insert "--" boundary "--\n") - (insert "\n--" boundary "--\n") - ))) + (cond + ((and (<= nparts 1)(not multipart)) + ;; It's a singular message. + (goto-char (point-min)) + (while (re-search-forward + mime-editor/single-part-tag-regexp nil t) + (setq tag + (buffer-substring (match-beginning 0) (match-end 0))) + (delete-region (match-beginning 0) (1+ (match-end 0))) + (setq contype (mime-editor/get-contype tag)) + (setq encoding (mime-editor/get-encoding tag)) + )) + (t + ;; It's a multipart message. + (goto-char (point-min)) + (and (mime-editor/translate-single-part-tag) + (while (mime-editor/translate-single-part-tag "\n")) + ) + ;; Define Content-Type as "multipart/mixed". + (setq contype + (concat "multipart/mixed;\n boundary=\"" boundary "\"")) + ;; Content-Transfer-Encoding must be "7bit". + ;; The following encoding can be `nil', but is + ;; specified as is since there is no way that a user + ;; specifies it. + (setq encoding "7bit") + ;; Insert the trailer. + (goto-char (point-max)) + (insert "\n--" boundary "--\n") + )) (list contype encoding boundary nparts) )))) @@ -1916,74 +1960,78 @@ 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. - )) - ;; 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)) + (let ((beg (point)) + (end (mime-editor/content-end)) ) + (goto-char end) + (or (looking-at mime-editor/beginning-tag-regexp) + (eobp) + (insert (mime-make-text-tag) "\n") + ) + (visible-region beg end) + (goto-char beg) + ) + (cond + ((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 (if charset + (intern (downcase 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 + (assq charset + mime-editor/charset-default-encoding-alist) + )) + (beg (mime-editor/content-beginning)) + ) + (encode-mime-charset-region beg (mime-editor/content-end) + charset) + (mime-encode-region beg (mime-editor/content-end) encoding) + (mime-editor/define-encoding encoding) + )) + (goto-char (mime-editor/content-end)) + ) + ((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) @@ -2000,93 +2048,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) - ))) - - -;; 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) - ))) - - -;; 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) - ))) - - -;; 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 - )) - - ;; Sun implementations (defun mime-voice-recorder-for-sun () @@ -2186,30 +2147,25 @@ a recording host instead of local host." (defun mime-editor/enclose-region (type beg end) (save-excursion (goto-char beg) - (let ((current (point)) - exist-prev-tag) - (save-excursion - (if (mime-editor/goto-tag) - (or (eq current (match-beginning 0)) - (setq exist-prev-tag t) - ))) + (let ((current (point))) (save-restriction (narrow-to-region beg end) - (goto-char beg) - (if exist-prev-tag - (insert "\n") - ) (insert (format "--<<%s>>-{\n" type)) (goto-char (point-max)) - (insert (format "\n--}-<<%s>>\n" type)) + (insert (format "--}-<<%s>>\n" type)) (goto-char (point-max)) ) - (if (and (not (looking-at mime-editor/single-part-tag-regexp)) - (not (eobp))) + (or (looking-at mime-editor/beginning-tag-regexp) + (eobp) (insert (mime-make-text-tag) "\n") - ) + ) ))) +(defun mime-editor/enclose-quote-region (beg end) + (interactive "*r") + (mime-editor/enclose-region "quote" beg end) + ) + (defun mime-editor/enclose-mixed-region (beg end) (interactive "*r") (mime-editor/enclose-region "mixed" beg end) @@ -2267,6 +2223,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-editor/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 ;;; @@ -2337,8 +2314,8 @@ a recording host instead of local host." (fields subject id number total separator) (insert fields) (insert (format "Subject: %s (%d/%d)\n" subject number total)) - (insert (format "Mime-Version: 1.0 (split by tm-edit %s)\n" - mime-editor/version)) + (insert (format "Mime-Version: 1.0 (split by %s)\n" + mime-editor/version-name)) (insert (format "\ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n" id number total separator)) @@ -2361,92 +2338,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 @@ -2454,28 +2385,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) @@ -2602,17 +2541,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)) + (boundary-pat + (concat "\n--" (regexp-quote boundary) "[ \t]*\n")) + ) + (re-search-forward boundary-pat nil t) + (let ((bb (match-beginning 0)) eb tag) + (setq tag (format "\n--<<%s>>-{\n" stype)) + (goto-char bb) + (insert tag) + (setq bb (+ bb (length tag))) + (re-search-forward + (concat "\n--" (regexp-quote boundary) "--[ \t]*\n") + nil t) + (setq eb (match-beginning 0)) + (replace-match (format "--}-<<%s>>\n" stype)) + (save-restriction + (narrow-to-region bb eb) + (goto-char (point-min)) + (while (re-search-forward boundary-pat nil t) + (let ((beg (match-beginning 0)) + end) + (delete-region beg (match-end 0)) + (save-excursion + (if (re-search-forward boundary-pat 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 (search-forward "\n\n" 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) + (decode-mime-charset-region + (point-min)(point-max) + (or charset default-mime-charset)) + ) + (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 + (mime-create-tag + (concat type "/" stype pstr) encoding)) + )) + )))) + (if code-conversion + (decode-mime-charset-region (point-min) (point-max) + default-mime-charset) + ) + )))) + +(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 + (concat "^\\(" (regexp-quote mail-header-separator) "\\)?$") + 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