home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.emacs.sources
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!uwm.edu!ux1.cso.uiuc.edu!news.cso.uiuc.edu!ux3.cso.uiuc.edu!marca
- From: marca@ncsa.uiuc.edu (Marc Andreessen)
- Subject: mime-compose.el (new & improved)
- Message-ID: <MARCA.92Nov6065415@wintermute.ncsa.uiuc.edu>
- Sender: usenet@news.cso.uiuc.edu (Net Noise owner)
- Organization: Nat'l Center for Supercomputing Applications
- Date: Fri, 6 Nov 1992 11:54:15 GMT
- Lines: 620
-
- A new version of mime-compose.el follows. New features are many and
- varied; most interesting is probably use of selective-display (so you
- never have to look at a bajillion lines of base64-encoded data).
- Second most interesting is on-the-fly audio recording (for IRIS
- platforms only, at the moment).
-
- This works under Emacs, Epoch, and Lucid Emacs (with an enhanced
- mail-mode popup menu for the latter).
-
- Feedback always welcome...
-
- Marc
-
- ;;; --------------------------------------------------------------------------
- ;;; File: --- mime-compose.el ---
- ;;; Author: Marc Andreessen (marca@ncsa.uiuc.edu)
- ;;; Additional code: Keith Waclena (k-waclena@uchicago.edu).
- ;;; Copyright (C) National Center for Supercomputing Applications, 1992.
- ;;;
- ;;; This program is free software; you can redistribute it and/or modify
- ;;; it under the terms of the GNU General Public License as published by
- ;;; the Free Software Foundation; either version 1, or (at your option)
- ;;; any later version.
- ;;;
- ;;; This program is distributed in the hope that it will be useful,
- ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;;; GNU General Public License for more details.
- ;;;
- ;;; You should have received a copy of the GNU General Public License
- ;;; along with your copy of Emacs; if not, write to the Free Software
- ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ;;;
- ;;; -------------------------------- CONTENTS --------------------------------
- ;;;
- ;;; mime-compose: Utility routines for composing MIME-compliant mail.
- ;;; $Revision: 1.16 $
- ;;; $Date: 1992/11/06 14:50:59 $
- ;;;
- ;;; ------------------------------ INSTRUCTIONS ------------------------------
- ;;;
- ;;; Use the normal Emacs mail composer (C-x m).
- ;;;
- ;;; (Or, use with Emacs mh-e by loading this file *after* loading mh-e.
- ;;; Try putting (require 'mime-compose) in mh-letter-mode-hook.)
- ;;;
- ;;; Do nothing special to prepare a message to have MIME elements
- ;;; included in it.
- ;;;
- ;;; The basic commands to add MIME elements (images, audio, etc.) to a
- ;;; message are as follows:
- ;;;
- ;;; mail-mode mh-e command
- ;;; ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~
- ;;; C-c g C-c C-m g Add a GIF file.
- ;;; C-c j C-c C-m j Add a JPEG file.
- ;;; C-c a C-c C-m a Add an audio file.
- ;;; C-c p C-c C-m p Add a PostScript file.
- ;;;
- ;;; (Note that mime-compose assumes you have the 'mmencode' program
- ;;; installed on your system. See 'WHAT MIME IS' below for more
- ;;; information on mmencode and the metamail distribution.)
- ;;;
- ;;; Some mime-compose commands create data themselves; these follow:
- ;;;
- ;;; C-c x C-c C-m x
- ;;; Add the result of an X-window dump. The program named in
- ;;; mime-xwd-command will be run, and the resulting dump will be
- ;;; inserted into the message.
- ;;; C-c s C-c C-m s
- ;;; Add an audio snippet, recorded on the fly. CURRENTLY THIS WORKS
- ;;; ONLY FOR SILICON GRAPHICS INDIGO AND 4D/35's. Recording begins
- ;;; immediately; press 'y' to end recording or 'n' to abort the
- ;;; whole process. The resulting audio file will be converted to
- ;;; standard mulaw format and incorporated into the message.
- ;;;
- ;;; If you have a raw binary file and MIME or mime-compose doesn't
- ;;; have built-in support for its format (e.g. an Emacs Lisp
- ;;; byte-compiled file), you can use:
- ;;;
- ;;; C-c r C-c C-m r
- ;;; Add a raw binary file. You will be prompted for both the
- ;;; filename and the content type of the file; if you do not give a
- ;;; content type, the default (application/octet-stream) will be
- ;;; used, and the recipient will be able to have his/her MIME mail
- ;;; handler extract the raw binary file from the message.
- ;;;
- ;;; Similarly, to include nonbinary (text) files using
- ;;; quoted-printable encoding, use:
- ;;;
- ;;; C-c n C-c C-m n
- ;;; Add a raw nonbinary (text) file. You will be prompted for both
- ;;; the filename and the content type of the file (which defaults to
- ;;; text/plain).
- ;;;
- ;;; In addition to including files and generating inclusions on the
- ;;; fly, you can also point to external elements: files that will not
- ;;; be included in the document, but can be accessed by the recipient
- ;;; in some other way (most commonly, via FTP). The following
- ;;; commands handle this:
- ;;;
- ;;; C-c e C-c C-m e
- ;;; Point to an external file (assumed to be accessable via
- ;;; anonymous FTP). You will be prompted for the name of the FTP
- ;;; site, the remote directory name, and remote filename, the remote
- ;;; file's content type, and a description of the remote file.
- ;;; C-c f C-c C-m f
- ;;; This is the same as 'C-c e', except that the file will be
- ;;; accessed via regular FTP rather than anonymous FTP -- a username
- ;;; and password will have to be provided by the recipient to gain
- ;;; access to the file.
- ;;;
- ;;; Note that whenever you are prompted for a content type, Emacs'
- ;;; completion feature is active: press TAB for a list of valid types.
- ;;; You can also enter a type not in the completion list.
- ;;;
- ;;; ---------------------------- ADDITIONAL NOTES ----------------------------
- ;;;
- ;;; If you are running Lucid Emacs, the mail-mode popup menu (attached
- ;;; to the third mouse button) will include mime-compose entries.
- ;;;
- ;;; After your message has been `mimified' (by including a MIME
- ;;; element), it is best not to put trailing text outside the final
- ;;; boundary at the end of the file -- such text will not be
- ;;; considered to be part of the message by MIME-compliant mail
- ;;; readers (although it will still be sent).
- ;;;
- ;;; A command that usually isn't necessary, but is provided in case
- ;;; you wish to send a plaintext message with the various MIME headers
- ;;; and boundaries, is:
- ;;;
- ;;; C-c m C-c C-m m Mimify a message.
- ;;;
- ;;; Note that Emacs' selective-display feature is used: only the first
- ;;; line of any encoded data file will be displayed, followed by
- ;;; ellipses (indicating that some data is not being shown). See the
- ;;; variable 'mime-use-selective-display' below.
- ;;;
- ;;; MIME messages can contain elements and structures not yet
- ;;; supported by mime-compose. If you have ideas or code for support
- ;;; that should be provided by mime-compose, please send them to the
- ;;; author.
- ;;;
- ;;; ------------------------ WHAT MIME-COMPOSE IS NOT ------------------------
- ;;;
- ;;; mime-compose is not a MIME message handler. It will not interpret
- ;;; MIME messages, display images, or anything similar.
- ;;;
- ;;; mime-compose is not intelligent enough (yet) to construct complex
- ;;; MIME messages (with nested boundaries, parallel message elements,
- ;;; and so on).
- ;;;
- ;;; mime-compose will not enforce correctness (MIME compliance) on
- ;;; your messages. mime-compose generates MIME-compliant message
- ;;; elements, but will sit quietly if you alter them or add your own
- ;;; incorrect elements.
- ;;;
- ;;; ------------------------------ WHAT MIME IS ------------------------------
- ;;;
- ;;; MIME defines a format for email messages containing non-plaintext
- ;;; elements (images, audio, etc.). MIME is detailed in Internet RFC
- ;;; 1341, by N. Borenstein and N. Freed. You can FTP this RFC from
- ;;; many archive sites, including uxc.cso.uiuc.edu.
- ;;;
- ;;; Few mail readers handle MIME messages, yet. However, most popular
- ;;; mail readers can be easily patched to feed MIME messages to a
- ;;; program called 'metamail', which can handle MIME messages. You
- ;;; can FTP metamail from thumper.bellcore.com in /pub/nsb as
- ;;; mm.tar.Z. Since mime-compose requires the existence of the
- ;;; program 'mmencode' (from the metamail distribution) to insert
- ;;; binary files into messages, it is a Good Idea to have metamail
- ;;; installed on your system.
- ;;;
- ;;; --------------------------------------------------------------------------
- ;;; LCD Archive Entry:
- ;;; mime-compose|Marc Andreessen|marca@ncsa.uiuc.edu
- ;;; |MIME-compliant message generation utilities.
- ;;; |$Date: 1992/11/06 14:50:59 $|$Revision: 1.16 $|
- ;;; --------------------------------------------------------------------------
-
- (provide 'mime-compose)
- (require 'sendmail)
-
- (defvar mime-primary-boundary "mysteryboxofun"
- "*Word used as a MIME boundary.")
-
- (defvar mime-xwd-command "xwd -frame"
- "*Command used to do a window dump under the X Window System.")
-
- (defvar mime-encode-base64-command "mmencode"
- "*Command used to encode in base64.")
-
- (defvar mime-encode-qp-command "mmencode -q"
- "*Command used to encode in quoted-printable.")
-
- (defvar mime-use-selective-display t
- "*Use selective-display to hide bodies of MIME enclosures.")
-
- (defvar mime-valid-include-types
- '(("image/gif" 1)
- ("image/jpeg" 2)
- ("image/x-xbm" 3)
- ("image/x-xwd" 4)
- ("application/postscript" 5)
- ("application/andrew-inset" 6)
- ("application/octet-stream" 7)
- ("text/richtext" 8)
- ("text/plain" 9)
- ("audio/basic" 10))
- "A list of valid content types for minibuffer completion.")
-
- (defun mime-primary-boundary ()
- "Return the current primary boundary."
- mime-primary-boundary)
-
- (defun mime-hide-region (from to hideflag)
- "Hides or shows lines from FROM to TO, according to FLAG."
- (let ((old (if hideflag ?\n ?\^M))
- (new (if hideflag ?\^M ?\n))
- (modp (buffer-modified-p)))
- (unwind-protect (progn
- (subst-char-in-region from to
- old new t))
- (set-buffer-modified-p modp))))
-
- (defun mime-maybe-hide-region (start end)
- "Hide the current region if mime-use-selective-display is T."
- (if mime-use-selective-display
- (mime-hide-region start end t)))
-
- (defun mime-mimify-message ()
- "Add MIME headers to a message. Add an initial informational message
- for mailreaders that don't process MIME automatically. Add an initial
- area for plaintext. Add a closing boundary at the end of the message.
- This function is safe to call more than once."
- (interactive)
- (let ((mail-header-separator (if (eq major-mode 'mh-letter-mode)
- "\n\n\\|^-+$"
- mail-header-separator)))
- (or
- (save-excursion
- (goto-char (point-min))
- (re-search-forward "^Mime-Version: "
- (save-excursion
- (goto-char (point-min))
- (re-search-forward mail-header-separator)
- (point))
- t))
- (let ((mime-virgin-message (save-excursion
- (next-line -1)
- (looking-at mail-header-separator))))
- (if mime-virgin-message
- (insert "\n"))
- ;; Configure selective-display if we want it...
- (save-excursion
- (save-excursion
- (goto-char (point-min))
- (re-search-forward mail-header-separator)
- (beginning-of-line)
- (insert "Mime-Version: 1.0\n")
- (insert "Content-Type: multipart/mixed;\n")
- (insert "\tboundary=" (mime-primary-boundary) "\n")
- (next-line 1)
- (let ((start (point)) end)
- (insert "> THIS IS A MESSAGE IN 'MIME' FORMAT.\n")
- (insert
- "> If you are reading this, your mail reader may not support MIME.\n")
- (insert
- "> Some parts of this message will be readable as plain text.\n")
- (setq end (point))
- (mime-maybe-hide-region start (- end 1)))
- (insert "\n")
- (goto-char (point-max))
- (insert "\n")
- (insert "\n")
- (insert "--" (mime-primary-boundary) "--\n"))
- (save-excursion
- (goto-char (point-min))
- (re-search-forward mail-header-separator)
- (beginning-of-line)
- ;; THIS HAS TO MATCH the number of lines of text included
- ;; as a message ``header'' above.
- (if mime-use-selective-display
- (next-line 3)
- (next-line 5))
- (insert "--" (mime-primary-boundary) "\n")
- (insert "Content-type: text/plain\n")
- (insert "\n"))
- (if mime-virgin-message
- (backward-delete-char 1)))))))
-
- (defun mime-include-file (filename content-type binary)
- "Include a file. If third argument BINARY is T, then the file
- is binary; else it's text."
- (mime-mimify-message)
- (push-mark)
- (insert "--" (mime-primary-boundary) "\n")
- (insert "Content-type: " content-type "\n")
- (if binary
- (insert "Content-Transfer-Encoding: base64\n")
- (insert "Content-Transfer-Encoding: quoted-printable\n"))
- (insert "\n")
- (let ((start (point)) end (seldisp selective-display))
- (next-line 1)
- (save-excursion
- (next-line -1)
- (insert-file filename))
- (setq end (point))
- (setq selective-display nil)
- (if binary
- (shell-command-on-region start end mime-encode-base64-command t)
- (shell-command-on-region start end mime-encode-qp-command t))
- (setq selective-display seldisp)
- (setq end (point))
- (mime-maybe-hide-region start (- end 1))
- (insert "\n")
- (insert "--" (mime-primary-boundary) "\n")
- (insert "Content-type: text/plain\n")
- (insert "\n\n")
- (next-line -1)))
-
- (defun mime-include-binary-file (filename content-type)
- "Include a binary file at point in a MIME message. Encode it
- in base64 mode."
- (mime-include-file filename content-type t))
-
- (defun mime-include-nonbinary-file (filename content-type)
- "Include a nonbinary file at point in a MIME message. Encode it
- in quoted-printable mode."
- (mime-include-file filename content-type nil))
-
- (defun mime-include-external (site directory name content-type description
- access-type)
- "Include an external pointer in a MIME message."
- (mime-mimify-message)
- (insert "--" (mime-primary-boundary) "\n")
- (insert "Content-type: message/external-body;\n")
- (insert "\taccess-type=\"" access-type "\";\n")
- (insert "\tsite=\"" site "\";\n")
- (insert "\tdirectory=\"" directory "\";\n")
- (insert "\tname=\"" name "\"\n")
- (insert "Content-description: " description "\n")
- (insert "\n")
- (insert "Content-type: " content-type "\n")
- (insert "\n")
- (insert "\n")
- (insert "--" (mime-primary-boundary) "\n")
- (insert "Content-type: text/plain\n")
- (insert "\n"))
-
- (defun mime-include-external-anonftp (site directory name description)
- "Include an external pointer (anonymous FTP) in a MIME message."
- (interactive "sFTP site: \nsRemote directory name: \nsRemote filename: \nsDescription: ")
- (let ((content-type
- (completing-read "Content type: " mime-valid-include-types
- nil nil nil)))
- ;; Unadvertised default.
- (if (string= content-type "")
- (setq content-type "application/octet-stream"))
- (mime-include-external site directory name content-type
- description "anon-ftp")))
-
- (defun mime-include-external-ftp (site directory name description)
- "Include an external pointer (regular FTP) in a MIME message."
- (interactive "sFTP site: \nsRemote directory name: \nsRemote filename: \nsDescription: ")
- (let ((content-type
- (completing-read "Content type: " mime-valid-include-types
- nil nil nil)))
- ;; Unadvertised default.
- (if (string= content-type "")
- (setq content-type "application/octet-stream"))
- (mime-include-external site directory name content-type
- description "ftp")))
-
- (defun mime-include-xwd-dump ()
- "Run xwd and include the results in a MIME message."
- (interactive)
- (mime-mimify-message)
- (push-mark)
- (insert "--" (mime-primary-boundary) "\n")
- (insert "Content-type: image/x-xwd\n")
- (insert "Content-Transfer-Encoding: base64\n")
- (insert "\n")
- (let ((start (point)) end (seldisp selective-display))
- (next-line 1)
- (save-excursion
- (next-line -1)
- (message "When crosshair cursor appears, click on window...")
- (sit-for 0)
- (call-process "/bin/sh" nil t nil "-c" mime-xwd-command)
- (message "")
- (sit-for 0))
- (setq end (point))
- (setq selective-display nil)
- (shell-command-on-region start end mime-encode-base64-command t)
- (setq selective-display seldisp)
- (setq end (point))
- (mime-maybe-hide-region start (- end 1))
- (insert "\n")
- (insert "--" (mime-primary-boundary) "\n")
- (insert "Content-type: text/plain\n")
- (insert "\n\n")
- (next-line -1)))
-
- (defvar mime-audio-file "/tmp/fooblatz")
- (defvar mime-audio-tmp-file "/tmp/fooblatz.aiff")
-
- (defun mime-grab-audio-snippet ()
- "Grab an audio snippet into hardcoded file /tmp/fooblatz.
- This only works on SGI Indigo's and PI/35's. Contributed code
- for Sparcs and other platforms is more than welcome."
- (let (audio-process done-flag)
- (setq audio-process
- (start-process "snippet" "snippet"
- "recordaiff" "-n" "1" "-s" "8" "-r" "8000"
- mime-audio-tmp-file))
- ;; Quick hack to make Emacs sit until recording is done.
- (setq done-flag
- (y-or-n-p "Press y when done recording (n to abort): "))
- (interrupt-process "snippet")
- ;; Wait until recordaiff has written data to disk. */
- (while (eq (process-status "snippet") 'run)
- (message "Waiting...")
- (sleep-for 1))
- ;; Kill off recordaiff and our buffer.
- (delete-process "snippet")
- (kill-buffer "snippet")
- ;; Remove the old mulaw file and do the conversion.
- (call-process "/bin/rm" nil nil nil "-f" mime-audio-file)
- (if done-flag
- (call-process "/usr/sbin/sfconvert" nil nil nil mime-audio-tmp-file
- mime-audio-file "-o" "mulaw"))
- (call-process "/bin/rm" nil nil nil "-f" mime-audio-tmp-file)
- ;; Return done flag. If nil, mime-include-audio-snippet should
- ;; clean up.
- done-flag))
-
- (defun mime-include-audio-snippet ()
- "Record a snippet of audio in a MIME message. This will only work
- on SGI IRIS Indigo's and PI/35's."
- (interactive)
- (if (eq (mime-grab-audio-snippet) t)
- (mime-include-binary-file mime-audio-file "audio/basic")))
-
- (defun mime-include-gif (filename)
- "Include a GIF file."
- (interactive "fGIF image filename: ")
- (mime-include-binary-file filename "image/gif"))
- (defun mime-include-jpeg (filename)
- "Include a JPEG file."
- (interactive "fJPEG image filename: ")
- (mime-include-binary-file filename "image/jpeg"))
- (defun mime-include-audio (filename)
- "Include an audio file."
- (interactive "fAudio filename: ")
- (mime-include-binary-file filename "audio/basic"))
- (defun mime-include-postscript (filename)
- "Include a PostScript file."
- (interactive "fPostScript filename: ")
- (mime-include-nonbinary-file filename "application/postscript"))
- (defun mime-include-raw-binary (filename)
- "Include a raw binary file."
- (interactive "fRaw binary filename: ")
- (let ((content-type
- (completing-read "Content type (RET for default): "
- mime-valid-include-types
- nil nil nil)))
- (if (string= content-type "")
- (setq content-type "application/octet-stream"))
- (mime-include-binary-file filename content-type)))
- (defun mime-include-raw-nonbinary (filename)
- "Include a raw binary file."
- (interactive "fRaw nonbinary filename: ")
- (let ((content-type
- (completing-read "Content type (RET for default): "
- mime-valid-include-types
- nil nil nil)))
- (if (string= content-type "")
- (setq content-type "text/plain"))
- (mime-include-nonbinary-file filename content-type)))
-
- ;;; -------------------------------- Keymaps ---------------------------------
-
- ;;; Add functions to basic mail mode.
- (define-key mail-mode-map "\C-cm" 'mime-mimify-message)
- (define-key mail-mode-map "\C-cg" 'mime-include-gif)
- (define-key mail-mode-map "\C-cj" 'mime-include-jpeg)
- (define-key mail-mode-map "\C-ca" 'mime-include-audio)
- (define-key mail-mode-map "\C-cp" 'mime-include-postscript)
- (define-key mail-mode-map "\C-cr" 'mime-include-raw-binary)
- (define-key mail-mode-map "\C-cn" 'mime-include-raw-nonbinary)
- (define-key mail-mode-map "\C-cx" 'mime-include-xwd-dump)
- (define-key mail-mode-map "\C-ce" 'mime-include-external-anonftp)
- (define-key mail-mode-map "\C-cf" 'mime-include-external-ftp)
- (define-key mail-mode-map "\C-cs" 'mime-include-audio-snippet)
-
- ;;; Add functions to MH letter mode.
- (if (boundp 'mh-letter-mode-map)
- (if (or (not (boundp 'mh-letter-mode-mime-map))
- (not mh-letter-mode-mime-map))
- (progn
- (setq mh-letter-mode-mime-map (make-sparse-keymap))
- (define-key mh-letter-mode-map "\C-c\C-m" mh-letter-mode-mime-map)
- (define-key mh-letter-mode-mime-map "m" 'mime-mimify-message)
- (define-key mh-letter-mode-mime-map "g" 'mime-include-gif)
- (define-key mh-letter-mode-mime-map "j" 'mime-include-jpeg)
- (define-key mh-letter-mode-mime-map "a" 'mime-include-audio)
- (define-key mh-letter-mode-mime-map "p" 'mime-include-postscript)
- (define-key mh-letter-mode-mime-map "r" 'mime-include-raw-binary)
- (define-key mh-letter-mode-mime-map "n" 'mime-include-raw-nonbinary)
- (define-key mh-letter-mode-mime-map "x" 'mime-include-xwd-dump)
- (define-key mh-letter-mode-mime-map "e"
- 'mime-include-external-anonftp)
- (define-key mh-letter-mode-mime-map "f"
- 'mime-include-external-ftp)
- (define-key mh-letter-mode-mime-map "s"
- 'mime-include-audio-snippet))))
-
- ;;; -------------------------------- Menubar ---------------------------------
-
- (defvar mime-running-lemacs (string-match "Lucid" emacs-version)
- "Non-nil if running Lucid Emacs.")
-
- ;; All we do at the moment is replace the popup menu defined in
- ;; Lucid Emacs 19.3's sendmail.el.
- (if mime-running-lemacs
- (progn
- (setq mail-mode-menu
- '("Mail Mode"
- "Sending Mail:"
- "----"
- ["Send and Exit" mail-send-and-exit t]
- ["Send Mail" mail-send t]
- ["Sent Via" mail-sent-via t]
- "----"
- "Go to Field:"
- "----"
- ["To:" mail-to t]
- ["Subject:" mail-subject t]
- ["CC:" mail-cc t]
- ["BCC:" mail-bcc t]
- ["Text" mail-text t]
- "----"
- "Miscellaneous Commands:"
- "----"
- ["Yank Original" mail-yank-original t]
- ["Fill Yanked Message" mail-fill-yanked-message t]
- ["Insert Signature" mail-signature t]
- "----"
- "MIME Inclusions:"
- "----"
- ["Include GIF File" mime-include-gif t]
- ["Include JPEG File" mime-include-jpeg t]
- ["Include Audio File" mime-include-audio t]
- ["Include PostScript File" mime-include-postscript t]
- ["Include XWD Dump" mime-include-xwd-dump t]
- ["Include Audio Snippet" mime-include-audio-snippet t]
- ["Include Raw Binary File" mime-include-raw-binary t]
- ["Include Raw Nonbinary File" mime-include-raw-nonbinary t]
- ["Include External AnonFTP" mime-include-external-anonftp t]
- ["Include External FTP" mime-include-external-ftp t]
- "----"
- ["Abort" kill-buffer t]
- ))))
-
- ;;; ----------------------------- New mail-send ------------------------------
-
- ;; If we're not running Lemacs, pop in a new mail-send routine.
- (if (not mime-running-lemacs)
- (defun mail-send ()
- "Send the message in the current buffer.
- If mail-interactive is non-nil, wait for success indication
- or error messages, and inform user.
- Otherwise any failure is reported in a message back to
- the user from the mailer."
- (interactive)
- (message "Sending...")
- (run-hooks 'mail-send-hook)
- (funcall send-mail-function)
- (set-buffer-modified-p nil)
- (delete-auto-save-file-if-necessary)
- (message "Sending...done")))
-
- ;;; --------------------------------- Hooks ----------------------------------
-
- ;; Author: Daniel LaLiberte (liberte@cs.uiuc.edu).
- (defun mime-postpend-unique-hook (hook-var hook-function)
- "Postpend HOOK-VAR with HOOK-FUNCTION, if it is not already an element.
- hook-var's value may be a single function or a list of functions."
- (if (boundp hook-var)
- (let ((value (symbol-value hook-var)))
- (if (and (listp value) (not (eq (car value) 'lambda)))
- (and (not (memq hook-function value))
- (set hook-var (append value (list hook-function))))
- (and (not (eq hook-function value))
- (set hook-var (append value (list hook-function))))))
- (set hook-var (list hook-function))))
-
- (defun mime-unfrob-selective-display ()
- "Turn off selective display throughout this buffer."
- (if mime-use-selective-display
- (progn
- (message "Unfrobbing selective-display...")
- (mime-hide-region (point-min) (point-max) nil))))
-
- ;; Before the message is sent, remove the selective display crap.
- (mime-postpend-unique-hook 'mail-send-hook 'mime-unfrob-selective-display)
-
- (defun mime-setup-hook-function ()
- (if mime-use-selective-display
- (setq selective-display t)))
-
- ;; During mail setup, activate selective-display if necessary.
- (mime-postpend-unique-hook 'mail-setup-hook 'mime-setup-hook-function)
-
- --
- Marc Andreessen
- Software Development Group
- National Center for Supercomputing Applications
- marca@ncsa.uiuc.edu
-