1 ;;; mh-mime --- mh-e support for composing MIME messages
2 ;; Time-stamp: <94/11/18 17:48:19 gildea>
4 ;; Copyright (C) 1993, 1995 Free Software Foundation, Inc.
6 ;; This file is part of GNU Emacs.
8 ;; GNU Emacs is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; GNU Emacs is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU Emacs; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 ;;; Internal support for mh-e package.
25 ;;; Support for generating an mhn composition file.
26 ;;; MIME is supported only by MH 6.8 or later.
30 ;; $Id: mh-mime.el,v 1.2 1995/04/09 22:30:35 kwzh Exp kwzh $
39 ;; paragraph code should not fill # lines if MIME enabled.
40 ;; implement mh-auto-edit-mhn (if non-nil, \\[mh-send-letter]
41 ;; invokes mh-edit-mhn automatically before sending.)
42 ;; actually, instead of mh-auto-edit-mhn,
43 ;; should read automhnproc from profile
44 ;; MIME option to mh-forward
45 ;; command to move to content-description insertion point
47 (defvar mh-mhn-args nil
48 "Extra arguments to have \\[mh-edit-mhn] pass to the \"mhn\" command.
49 The arguments are passed to mhn if \\[mh-edit-mhn] is given a
50 prefix argument. Normally default arguments to mhn are specified in the
53 (defvar mh-edit-mhn-hook nil
54 "Invoked on the formatted letter by \\<mh-letter-mode-map>\\[mh-edit-mhn].")
56 (defvar mh-mime-content-types
57 '(("text/plain") ("text/richtext")
58 ("multipart/mixed") ("multipart/alternative") ("multipart/digest")
59 ("multipart/parallel")
60 ("message/rfc822") ("message/partial") ("message/external-body")
61 ("application/octet-stream") ("application/postscript")
62 ("image/jpeg") ("image/gif")
65 "Legal MIME content types.")
67 (defun mh-mhn-compose-insertion (pathname type description)
68 "Add a directive to insert a message part from a file.
69 This is the typical way to insert non-text parts in a message.
70 Arguments are PATHNAME, which tells where to find the file, TYPE, the
71 MIME content type, and DESCRIPTION, a line of text for the
72 Content-description header. See also \\[mh-edit-mhn]."
74 (read-file-name "Insert contents of: ")
75 (completing-read "Content-type: "
76 mh-mime-content-types nil nil nil)
77 (read-string "Content-description: ")))
78 (mh-mhn-compose-type pathname type description))
80 (defun mh-mhn-compose-type (pathname type
81 &optional description attributes comment)
85 (insert "; " attributes))
87 (insert " (" comment ")"))
91 (insert "] " (expand-file-name pathname))
95 (defun mh-mhn-compose-anon-ftp (host pathname type description)
96 "Add a directive for an anonymous ftp external body part.
97 This directive tells MH to include a reference to a
98 message/external-body part retrievable by anonymous FTP. Arguments
99 are HOST and PATHNAME, which tell where to find the file, TYPE, the
100 MIME content type, and DESCRIPTION, a line of text for the
101 Content-description header. See also \\[mh-edit-mhn]."
103 (read-string "Remote host: ")
104 (read-string "Remote pathname: ")
105 (completing-read "External Content-type: "
106 mh-mime-content-types nil nil nil)
107 (read-string "External Content-description: ")))
108 (mh-mhn-compose-external-type "anon-ftp" host pathname
111 (defun mh-mhn-compose-external-compressed-tar (host pathname description)
112 "Add a directive to include a reference to a compressed tar file.
113 The file should be available via anonymous ftp. This directive
114 tells MH to include a reference to a message/external-body part.
115 Arguments are HOST and PATHNAME, which tell where to find the file, and
116 DESCRIPTION, a line of text for the Content-description header.
117 See also \\[mh-edit-mhn]."
119 (read-string "Remote host: ")
120 (read-string "Remote pathname: ")
121 (read-string "Tar file Content-description: ")))
122 (mh-mhn-compose-external-type "anon-ftp" host pathname
123 "application/octet-stream"
125 "type=tar; conversions=x-compress"
129 (defun mh-mhn-compose-external-type (access-type host pathname type
130 &optional description
131 attributes extra-params comment)
135 (insert "; " attributes))
137 (insert " (" comment ") "))
140 (insert description))
142 (insert "access-type=" access-type "; ")
143 (insert "site=" host)
144 (insert "; name=" (file-name-nondirectory pathname))
145 (insert "; directory=\"" (file-name-directory pathname) "\"")
147 (insert "; " extra-params))
150 (defun mh-mhn-compose-forw (&optional description folder messages)
151 "Add a forw directive to this message.
152 This directive tells MH to include the named messages in this one.
153 Arguments are DESCRIPTION, a line of text for the Content-description header,
154 FOLDER and MESSAGES, which name the message(s) to be forwarded.
155 See also \\[mh-edit-mhn]."
157 (read-string "Forw Content-description: ")
158 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil)
159 (read-string (format "Messages%s: "
161 (format " [%d]" mh-sent-from-msg)
166 (not (string= description ""))
167 (insert description))
170 (not (string= folder ""))
173 (not (string= messages "")))
174 (let ((start (point)))
175 (insert " " messages)
176 (subst-char-in-region start (point) ?, ? ))
178 (insert " " (int-to-string mh-sent-from-msg))))
181 (defun mh-edit-mhn (&optional extra-args)
182 "Format the current draft for MIME, expanding any mhn directives.
183 Process the current draft with the mhn program, which,
184 using directives already inserted in the draft, fills in
185 all the MIME components and header fields.
186 This step should be done last just before sending the message.
187 The mhn program is part of MH version 6.8 or later.
188 The `\\[mh-revert-mhn-edit]' command undoes this command.
189 The arguments in the list `mh-mhn-args' are passed to mhn
190 if this function is passed an argument.
192 For assistance with creating mhn directives to insert
193 various types of components in a message, see
194 \\[mh-mhn-compose-insertion] (generic insertion from a file),
195 \\[mh-mhn-compose-anon-ftp] (external reference to file via anonymous ftp),
196 \\[mh-mhn-compose-external-compressed-tar] \
197 \(reference to compressed tar file via anonymous ftp), and
198 \\[mh-mhn-compose-forw] (forward message)."
201 (message "mhn editing...")
202 (mh-exec-cmd-error (format "mhdraft=%s" buffer-file-name)
203 "mhn" (if extra-args mh-mhn-args) buffer-file-name)
205 (message "mhn editing...done")
206 (run-hooks 'mh-edit-mhn-hook))
209 (defun mh-revert-mhn-edit (noconfirm)
210 "Undoes the effect of \\[mh-edit-mhn] by reverting to the backup file.
211 Optional non-nil argument means don't ask for confirmation."
213 (if (null buffer-file-name)
214 (error "Buffer does not seem to be associated with any file"))
215 (let ((backup-strings '("," "#"))
217 (while (and backup-strings
220 (concat (file-name-directory buffer-file-name)
222 (file-name-nondirectory buffer-file-name)
224 (setq backup-strings (cdr backup-strings)))
226 (error "mhn backup file for %s no longer exists!" buffer-file-name))
228 (yes-or-no-p (format "Revert buffer from file %s? "
230 (error "mhn edit revert not confirmed."))
231 (let ((buffer-read-only nil))
233 (insert-file-contents backup-file))
234 (after-find-file nil)))