Some fixes to follow coding conventions in files from Gnus.
[bpt/emacs.git] / lisp / mail / mh-mime.el
CommitLineData
c26cf6c8 1;;; mh-mime --- mh-e support for composing MIME messages
b4b1e78a 2;; Time-stamp: <95/08/19 16:45:17 gildea>
c26cf6c8 3
847b8219 4;; Copyright (C) 1993, 1995 Free Software Foundation, Inc.
c26cf6c8 5
b4b1e78a 6;; This file is part of mh-e, part of GNU Emacs.
c26cf6c8 7
9b7bc076 8;; GNU Emacs is free software; you can redistribute it and/or modify
c26cf6c8
RS
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)
11;; any later version.
12
9b7bc076 13;; GNU Emacs is distributed in the hope that it will be useful,
c26cf6c8
RS
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.
17
18;; You should have received a copy of the GNU General Public License
b578f267
EN
19;; along with GNU Emacs; see the file COPYING. If not, write to the
20;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21;; Boston, MA 02111-1307, USA.
c26cf6c8
RS
22
23;;; Commentary:
24
b578f267
EN
25;; Internal support for mh-e package.
26;; Support for generating an mhn composition file.
27;; MIME is supported only by MH 6.8 or later.
c26cf6c8 28
847b8219
KH
29;;; Change Log:
30
0cf950b1 31;; $Id: mh-mime.el,v 1.7 1997/01/13 03:25:05 rms Exp kwzh $
847b8219 32
c26cf6c8
RS
33;;; Code:
34
35(provide 'mh-mime)
36(require 'mh-comp)
37
38
39;; To do:
40;; paragraph code should not fill # lines if MIME enabled.
41;; implement mh-auto-edit-mhn (if non-nil, \\[mh-send-letter]
42;; invokes mh-edit-mhn automatically before sending.)
43;; actually, instead of mh-auto-edit-mhn,
44;; should read automhnproc from profile
45;; MIME option to mh-forward
46;; command to move to content-description insertion point
47
847b8219
KH
48(defvar mh-mhn-args nil
49 "Extra arguments to have \\[mh-edit-mhn] pass to the \"mhn\" command.
50The arguments are passed to mhn if \\[mh-edit-mhn] is given a
51prefix argument. Normally default arguments to mhn are specified in the
52MH profile.")
53
54(defvar mh-edit-mhn-hook nil
55 "Invoked on the formatted letter by \\<mh-letter-mode-map>\\[mh-edit-mhn].")
56
42c21202 57;;;###autoload
c26cf6c8
RS
58(defvar mh-mime-content-types
59 '(("text/plain") ("text/richtext")
60 ("multipart/mixed") ("multipart/alternative") ("multipart/digest")
61 ("multipart/parallel")
62 ("message/rfc822") ("message/partial") ("message/external-body")
63 ("application/octet-stream") ("application/postscript")
64 ("image/jpeg") ("image/gif")
65 ("audio/basic")
66 ("video/mpeg"))
42c21202 67 "Legal MIME content types. See documentation for \\[mh-edit-mhn].")
c26cf6c8 68
3fda54a2 69(defun mh-mhn-compose-insertion (filename type description attributes)
42c21202 70 "Add a directive to insert a MIME message part from a file.
c26cf6c8 71This is the typical way to insert non-text parts in a message.
3fda54a2 72Arguments are FILENAME, which tells where to find the file, TYPE, the
847b8219
KH
73MIME content type, and DESCRIPTION, a line of text for the
74Content-description header. See also \\[mh-edit-mhn]."
3fda54a2
RS
75 (interactive (let ((filename (read-file-name "Insert contents of: ")))
76 (list
77 filename
78 (completing-read "Content-type: "
c26cf6c8 79 mh-mime-content-types nil nil nil)
3fda54a2
RS
80 (read-string "Content-description: ")
81 (read-string "Content-Attributes: "
0cf950b1
KH
82 (concat "name=\""
83 (file-name-nondirectory filename)
84 "\"")))))
3fda54a2 85 (mh-mhn-compose-type filename type description attributes ))
c26cf6c8 86
3fda54a2 87(defun mh-mhn-compose-type (filename type
c26cf6c8
RS
88 &optional description attributes comment)
89 (beginning-of-line)
90 (insert "#" type)
91 (and attributes
92 (insert "; " attributes))
93 (and comment
94 (insert " (" comment ")"))
95 (insert " [")
96 (and description
97 (insert description))
3fda54a2 98 (insert "] " (expand-file-name filename))
c26cf6c8
RS
99 (insert "\n"))
100
101
3fda54a2 102(defun mh-mhn-compose-anon-ftp (host filename type description)
42c21202 103 "Add a directive for a MIME anonymous ftp external body part.
847b8219
KH
104This directive tells MH to include a reference to a
105message/external-body part retrievable by anonymous FTP. Arguments
3fda54a2 106are HOST and FILENAME, which tell where to find the file, TYPE, the
847b8219
KH
107MIME content type, and DESCRIPTION, a line of text for the
108Content-description header. See also \\[mh-edit-mhn]."
c26cf6c8
RS
109 (interactive (list
110 (read-string "Remote host: ")
3fda54a2 111 (read-string "Remote filename: ")
c26cf6c8
RS
112 (completing-read "External Content-type: "
113 mh-mime-content-types nil nil nil)
114 (read-string "External Content-description: ")))
3fda54a2 115 (mh-mhn-compose-external-type "anon-ftp" host filename
c26cf6c8
RS
116 type description))
117
3fda54a2 118(defun mh-mhn-compose-external-compressed-tar (host filename description)
42c21202 119 "Add a directive to include a MIME reference to a compressed tar file.
847b8219
KH
120The file should be available via anonymous ftp. This directive
121tells MH to include a reference to a message/external-body part.
3fda54a2 122Arguments are HOST and FILENAME, which tell where to find the file, and
847b8219 123DESCRIPTION, a line of text for the Content-description header.
c26cf6c8
RS
124See also \\[mh-edit-mhn]."
125 (interactive (list
126 (read-string "Remote host: ")
3fda54a2 127 (read-string "Remote filename: ")
c26cf6c8 128 (read-string "Tar file Content-description: ")))
3fda54a2 129 (mh-mhn-compose-external-type "anon-ftp" host filename
c26cf6c8
RS
130 "application/octet-stream"
131 description
132 "type=tar; conversions=x-compress"
133 "mode=image"))
134
135
3fda54a2 136(defun mh-mhn-compose-external-type (access-type host filename type
c26cf6c8
RS
137 &optional description
138 attributes extra-params comment)
139 (beginning-of-line)
140 (insert "#@" type)
141 (and attributes
142 (insert "; " attributes))
143 (and comment
144 (insert " (" comment ") "))
145 (insert " [")
146 (and description
147 (insert description))
148 (insert "] ")
149 (insert "access-type=" access-type "; ")
150 (insert "site=" host)
3fda54a2
RS
151 (insert "; name=" (file-name-nondirectory filename))
152 (insert "; directory=\"" (file-name-directory filename) "\"")
c26cf6c8
RS
153 (and extra-params
154 (insert "; " extra-params))
155 (insert "\n"))
156
847b8219 157(defun mh-mhn-compose-forw (&optional description folder messages)
42c21202 158 "Add a forw directive to this message, to forward a message with MIME.
c26cf6c8
RS
159This directive tells MH to include the named messages in this one.
160Arguments are DESCRIPTION, a line of text for the Content-description header,
42c21202 161and FOLDER and MESSAGES, which name the message(s) to be forwarded.
c26cf6c8
RS
162See also \\[mh-edit-mhn]."
163 (interactive (list
164 (read-string "Forw Content-description: ")
847b8219 165 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil)
c26cf6c8
RS
166 (read-string (format "Messages%s: "
167 (if mh-sent-from-msg
168 (format " [%d]" mh-sent-from-msg)
847b8219 169 "")))))
c26cf6c8
RS
170 (beginning-of-line)
171 (insert "#forw [")
172 (and description
173 (not (string= description ""))
174 (insert description))
175 (insert "]")
176 (and folder
177 (not (string= folder ""))
178 (insert " " folder))
847b8219
KH
179 (if (and messages
180 (not (string= messages "")))
c26cf6c8 181 (let ((start (point)))
847b8219 182 (insert " " messages)
c26cf6c8
RS
183 (subst-char-in-region start (point) ?, ? ))
184 (if mh-sent-from-msg
185 (insert " " (int-to-string mh-sent-from-msg))))
186 (insert "\n"))
187
847b8219
KH
188(defun mh-edit-mhn (&optional extra-args)
189 "Format the current draft for MIME, expanding any mhn directives.
190Process the current draft with the mhn program, which,
191using directives already inserted in the draft, fills in
c26cf6c8
RS
192all the MIME components and header fields.
193This step should be done last just before sending the message.
194The mhn program is part of MH version 6.8 or later.
195The `\\[mh-revert-mhn-edit]' command undoes this command.
847b8219
KH
196The arguments in the list `mh-mhn-args' are passed to mhn
197if this function is passed an argument.
198
199For assistance with creating mhn directives to insert
c26cf6c8
RS
200various types of components in a message, see
201\\[mh-mhn-compose-insertion] (generic insertion from a file),
202\\[mh-mhn-compose-anon-ftp] (external reference to file via anonymous ftp),
203\\[mh-mhn-compose-external-compressed-tar] \
204\(reference to compressed tar file via anonymous ftp), and
205\\[mh-mhn-compose-forw] (forward message)."
847b8219 206 (interactive "*P")
c26cf6c8
RS
207 (save-buffer)
208 (message "mhn editing...")
847b8219
KH
209 (mh-exec-cmd-error (format "mhdraft=%s" buffer-file-name)
210 "mhn" (if extra-args mh-mhn-args) buffer-file-name)
c26cf6c8 211 (revert-buffer t t)
847b8219
KH
212 (message "mhn editing...done")
213 (run-hooks 'mh-edit-mhn-hook))
c26cf6c8
RS
214
215
216(defun mh-revert-mhn-edit (noconfirm)
217 "Undoes the effect of \\[mh-edit-mhn] by reverting to the backup file.
847b8219 218Optional non-nil argument means don't ask for confirmation."
c26cf6c8
RS
219 (interactive "*P")
220 (if (null buffer-file-name)
221 (error "Buffer does not seem to be associated with any file"))
222 (let ((backup-strings '("," "#"))
223 backup-file)
224 (while (and backup-strings
225 (not (file-exists-p
226 (setq backup-file
227 (concat (file-name-directory buffer-file-name)
228 (car backup-strings)
229 (file-name-nondirectory buffer-file-name)
230 ".orig")))))
231 (setq backup-strings (cdr backup-strings)))
232 (or backup-strings
233 (error "mhn backup file for %s no longer exists!" buffer-file-name))
234 (or noconfirm
235 (yes-or-no-p (format "Revert buffer from file %s? "
236 backup-file))
237 (error "mhn edit revert not confirmed."))
238 (let ((buffer-read-only nil))
239 (erase-buffer)
240 (insert-file-contents backup-file))
241 (after-find-file nil)))