home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / gnu / emacs / help / 4712 < prev    next >
Encoding:
Text File  |  1992-11-07  |  23.2 KB  |  593 lines

  1. Newsgroups: gnu.emacs.help
  2. Path: sparky!uunet!charon.amdahl.com!pacbell.com!decwrl!ames!saimiri.primate.wisc.edu!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ncsa.uiuc.edu!marca
  3. From: marca@ncsa.uiuc.edu (Marc Andreessen)
  4. Subject: Frustration with subst-char-in-region...
  5. Message-ID: <MARCA.92Nov5045603@wintermute.ncsa.uiuc.edu>
  6. Sender: gnulists@ai.mit.edu
  7. Organization: Nat'l Center for Supercomputing Applications
  8. Date: Thu, 5 Nov 1992 09:56:03 GMT
  9. Lines: 582
  10.  
  11. I'm having troubles with subst-char-in-region, and I'll be damned if I
  12. can figure out why.
  13.  
  14. The following function is being used in mime-compose.el (the
  15. complete file is at the end of the message).
  16.  
  17. (defun mime-hide-region (from to hideflag)
  18.   "Hides or shows lines from FROM to TO, according to FLAG."
  19.   (let ((old (if hideflag ?\n ?\^M))
  20.         (new (if hideflag ?\^M ?\n))
  21.         (modp (buffer-modified-p)))
  22.     (unwind-protect (progn
  23.                       (subst-char-in-region from to
  24.                                             old new t))
  25.       (set-buffer-modified-p modp))))
  26.  
  27. This is ripped off almost verbatim from code in outline.el/hideif.el,
  28. except modified to take T or NIL for a third arg instead of ?\n or
  29. ?\^M.  (I had the same problem I'll describe with the original
  30. routine.)
  31.  
  32. So this routine is used to hide and unhide certain regions of a
  33. buffer, and it works for that.  So far so good.  But in the course of
  34. going from unhidden to hidden to unhidden, the text in the hidden
  35. region becomes corrupted.  Examples follow:
  36.  
  37. CBEeHChQ4GLDBg0RaqAJgeZEDSliBOnShZIqqtCoXUu5cmXLIBoiJKhY169AnH4pZngR6M+h
  38. CBEeHChQ4GLDBgoRaqAJgeZECiliBOnShZIqqtCoXUu5cmXLIBoiJKhY169AnH4pZngR6M+h
  39.               ^         ^^
  40.  
  41. gnQLRO47M0IGDTFivKCyNKVilI2X/jWUWTl68oHKkdckmMIOnkaGKHVq9OULkyFDllDp8oYS
  42. gnQLRO47M0IGCjFivKCyNKVilI2X/jWUWTl68oHKkdckmMIOnkaGKHVq9OULkyFDllDp8oYS
  43.              ^
  44.  
  45. gaXwhkiJmUQNN9xQA4NEfmFWV3npUUcTZhCEEAh8Q32hxhBKBNEkE6bhgcdOh/xhSGiNdCKb
  46. gaXwhkiJmUQKN9xQA4NEfmFWV3npUUcTZhCEEAh8Q32hxhBKBNEkE6bhgcdOh/xhSGiNdCKb
  47.            ^
  48.  
  49. luFwWQ1t/sOZ9aBaZuGWFla9qcPOWLud5WFfkD4614cPFHATQRmckMIJytbg7BFAPMAoe2l8
  50. luFwWQpt/sOZ9aBaZuGWFla9qcPOWLud5WFfkD4614cPFHATQRmckMIJytbg7BFAPMAoe2l8
  51.       ^
  52.  
  53. This has been tested under both Epoch 4.2 (Emacs 18.58-derived) and
  54. raw Emacs 18.59.  To see this for yourself, use mime-compose.el below,
  55. and compose two messages containing a GIF file: set
  56. mime-use-selective-display to T for one message and to NIL for the
  57. other message.
  58.  
  59. Somebody please tell me I'm making a really stupid mistake.  (And then
  60. tell me what it is.)
  61.  
  62. Thanks,
  63.  
  64. Marc
  65.  
  66. ;;; --------------------------------------------------------------------------
  67. ;;; File: --- mime-compose.el ---
  68. ;;; Author: Marc Andreessen (marca@ncsa.uiuc.edu)
  69. ;;; Copyright (C) National Center for Supercomputing Applications, 1992.
  70. ;;;
  71. ;;; Further hacked by: Keith Waclena (k-waclena@uchicago.edu).
  72. ;;;
  73. ;;; This program is free software; you can redistribute it and/or modify
  74. ;;; it under the terms of the GNU General Public License as published by
  75. ;;; the Free Software Foundation; either version 1, or (at your option)
  76. ;;; any later version.
  77. ;;;
  78. ;;; This program is distributed in the hope that it will be useful,
  79. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  80. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  81. ;;; GNU General Public License for more details.
  82. ;;;
  83. ;;; You should have received a copy of the GNU General Public License
  84. ;;; along with your copy of Emacs; if not, write to the Free Software
  85. ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  86. ;;;
  87. ;;; CONTENTS
  88. ;;;
  89. ;;; mime-compose: Utility routines for composing MIME-compliant mail.
  90. ;;; $Revision: 1.8 $
  91. ;;; $Date: 1992/11/05 08:23:25 $
  92. ;;;
  93. ;;; ------------------------------ INSTRUCTIONS ------------------------------
  94. ;;;
  95. ;;; Use the normal Emacs mail composer (C-x m).
  96. ;;;
  97. ;;; (Or, use with Emacs mh-e by loading this file *after* loading mh-e.
  98. ;;; Try putting (require 'mime-compose) in mh-letter-mode-hook.)
  99. ;;;
  100. ;;; Do nothing special to prepare a message to have MIME elements
  101. ;;; included in it.
  102. ;;;
  103. ;;; The basic commands to add MIME elements (images, audio, etc.) to a
  104. ;;; message are as follows:
  105. ;;;
  106. ;;; mail-mode  mh-e         command
  107. ;;; ---------  ---------    -------
  108. ;;; C-c g      C-c C-m g    Add a GIF file.
  109. ;;; C-c j      C-c C-m j    Add a JPEG file.
  110. ;;; C-c a      C-c C-m a    Add a (basic) audio file.
  111. ;;; C-c p      C-c C-m p    Add a PostScript file.
  112. ;;;
  113. ;;; (Note that mime-compose assumes you have the 'mmencode' program
  114. ;;; installed on your system.  See 'WHAT MIME IS' below for more
  115. ;;; information on mmencode and the metamail distribution.)
  116. ;;;
  117. ;;; Some mime-compose commands create data themselves; these follow:
  118. ;;;
  119. ;;; C-c x     C-c C-m x
  120. ;;;   Add the result of an X-window dump.  The program named in
  121. ;;;   mime-xwd-command will be run, and the resulting dump will be
  122. ;;;   inserted into the message.
  123. ;;;
  124. ;;; If you have a raw binary file and MIME doesn't have built-in
  125. ;;; support for it (e.g. an Emacs Lisp byte-compiled file), you can
  126. ;;; use:
  127. ;;;
  128. ;;; C-c r     C-c C-m r
  129. ;;;   Add a raw binary file.  You will be prompted for both the
  130. ;;;   filename and the content type of the file; if you do not give a
  131. ;;;   content type, the default (application/octet-stream) will be
  132. ;;;   used, and the recipient will be able to have his/her MIME mail
  133. ;;;   handler extract the raw binary file from the message.
  134. ;;;
  135. ;;; In addition to including files and generating inclusions on the
  136. ;;; fly, you can also point to external elements: files that will not
  137. ;;; be included in the document, but can be accessed by the recipient
  138. ;;; in some other way (most commonly, via FTP).  The following
  139. ;;; commands handle this:
  140. ;;;
  141. ;;; C-c e     C-c C-m e
  142. ;;;   Point to an external file (assumed to be accessable via
  143. ;;;   anonymous FTP).  You will be prompted for the name of the FTP
  144. ;;;   site, the remote directory name, and remote filename, the remote
  145. ;;;   file's content type, and a description of the remote file.
  146. ;;;   Content type can be any MIME content type (examples include
  147. ;;;   'image/gif', 'audio/basic', and 'application/postscript'; see
  148. ;;;   the MIME RFC and your local mailcap file for more information).
  149. ;;; C-c f     C-c C-m f
  150. ;;;   This is the same as 'C-c e', except that the file will be
  151. ;;;   accessed via regular FTP rather than anonymous FTP -- a username
  152. ;;;   and password will have to be provided by the recipient to gain
  153. ;;;   access to the file.
  154. ;;;
  155. ;;; ---------------------------- ADDITIONAL NOTES ----------------------------
  156. ;;;
  157. ;;; If you are running Lucid Emacs, the mail-mode popup menu (attached
  158. ;;; to the third mouse button) will include mime-compose entries.
  159. ;;;
  160. ;;; After your message has been `mimified' (by including a MIME
  161. ;;; element), it is best not to put trailing text outside the final
  162. ;;; boundary at the end of the file -- such text will not be
  163. ;;; considered to be part of the message by MIME-compliant mail
  164. ;;; readers (although it will still be sent).
  165. ;;;
  166. ;;; A command that usually isn't necessary, but is provided in case
  167. ;;; you wish to send a plaintext message with the various MIME headers
  168. ;;; and boundaries, is:
  169. ;;;
  170. ;;; C-c m     C-c C-m m     Mimify a message.
  171. ;;;
  172. ;;; MIME messages can contain elements and structures not yet
  173. ;;; supported by mime-compose.  If you have ideas or code, please send
  174. ;;; them to the author.
  175. ;;;
  176. ;;; ------------------------ WHAT MIME-COMPOSE IS NOT ------------------------
  177. ;;;
  178. ;;; mime-compose is not a MIME message handler.  It will not interpret
  179. ;;; MIME messages, display images, or anything similar.
  180. ;;;
  181. ;;; mime-compose is not intelligent enough (yet) to construct complex
  182. ;;; MIME messages (with nested boundaries, parallel message elements,
  183. ;;; and so on).
  184. ;;;
  185. ;;; mime-compose will not enforce correctness (MIME compliance) on
  186. ;;; your messages.  mime-compose generates MIME-compliant message
  187. ;;; elements, but will sit quietly if you alter them or add your own
  188. ;;; incorrect elements.
  189. ;;;
  190. ;;; ------------------------------ WHAT MIME IS ------------------------------
  191. ;;;
  192. ;;; MIME defines a format for email messages containing non-plaintext
  193. ;;; elements (images, audio, etc.).  MIME is detailed in Internet RFC
  194. ;;; 1341, by N. Borenstein and N. Freed.  You can FTP this RFC from
  195. ;;; many archive sites, including uxc.cso.uiuc.edu.
  196. ;;;
  197. ;;; Few mail readers handle MIME messages, yet.  However, most popular
  198. ;;; mail readers can be easily patched to feed MIME messages to a
  199. ;;; program called 'metamail', which can handle MIME messages.  You
  200. ;;; can FTP metamail from thumper.bellcore.com in /pub/nsb as
  201. ;;; mm.tar.Z.  Since mime-compose requires the existence of the
  202. ;;; program 'mmencode' (from the metamail distribution) to insert
  203. ;;; binary files into messages, it is a Good Idea to have metamail
  204. ;;; installed on your system.
  205. ;;;
  206. ;;; --------------------------------------------------------------------------
  207. ;;; LCD Archive Entry:
  208. ;;; mime-compose|Marc Andreessen|marca@ncsa.uiuc.edu
  209. ;;; |MIME-compliant message generation utilities.
  210. ;;; |$Date: 1992/11/05 08:23:25 $|$Revision: 1.8 $|
  211. ;;; --------------------------------------------------------------------------
  212.  
  213. (provide 'mime-compose)
  214. (require 'sendmail)
  215.  
  216. (defvar mime-primary-boundary "outtahere"
  217.   "*Word used as a MIME boundary.")
  218.  
  219. (defvar mime-xwd-command "xwd -frame"
  220.   "*Command used to do a window dump under the X Window System.")
  221.  
  222. (defvar mime-use-selective-display nil
  223.   "*Use selective-display to hide bodies of MIME enclosures.
  224. Do NOT set this to T yet; it's not ready.")
  225.  
  226. (defun mime-primary-boundary ()
  227.   "Return the current primary boundary."
  228.   mime-primary-boundary)
  229.  
  230. (defun mime-hide-region (from to hideflag)
  231.   "Hides or shows lines from FROM to TO, according to FLAG."
  232.   (let ((old (if hideflag ?\n ?\^M))
  233.         (new (if hideflag ?\^M ?\n))
  234.         (modp (buffer-modified-p)))
  235.     (unwind-protect (progn
  236.                       (subst-char-in-region from to
  237.                                             old new t))
  238.       (set-buffer-modified-p modp))))
  239.  
  240. (defun mime-mimify-message ()
  241.   "Add MIME headers to a message.  Add an initial informational message
  242. for mailreaders that don't process MIME automatically.  Add an initial
  243. area for plaintext.  Add a closing boundary at the end of the message.
  244. This function is safe to call more than once."
  245.   (interactive)
  246.   (let ((mail-header-separator (if (eq major-mode 'mh-letter-mode)
  247.                    "\n\n\\|^-+$"
  248.                  mail-header-separator)))
  249.     (or
  250.      (save-excursion
  251.        (goto-char (point-min))
  252.        (re-search-forward "^Mime-Version: "
  253.                           (save-excursion
  254.                             (goto-char (point-min))
  255.                             (re-search-forward mail-header-separator)
  256.                             (point))
  257.                           t))
  258.      (let ((mime-virgin-message (save-excursion
  259.                                   (next-line -1)
  260.                                   (looking-at mail-header-separator))))
  261.        (if mime-virgin-message
  262.            (insert "\n"))
  263.        ;; Configure selective-display if we want it...
  264.        (if mime-use-selective-display
  265.            (setq selective-display t))
  266.        (save-excursion
  267.          (save-excursion
  268.            (goto-char (point-min))
  269.            (re-search-forward mail-header-separator)
  270.            (beginning-of-line)
  271.            (insert "Mime-Version: 1.0\n")
  272.            (insert "Content-Type: multipart/mixed;\n")
  273.            (insert "\tboundary=" (mime-primary-boundary) "\n")
  274.            (next-line 1)
  275.            (insert "> THIS IS A MESSAGE IN 'MIME' FORMAT.\n")
  276.            (insert 
  277.             "> If you are reading this, your mail reader may not support MIME.\n")
  278.            (insert 
  279.             "> Some parts of this message will be readable as plain text.\n")
  280.            (insert "\n")
  281.            (goto-char (point-max))
  282.            (insert "\n")
  283.            (insert "\n")
  284.            (insert "--" (mime-primary-boundary) "--\n"))
  285.          (save-excursion
  286.            (goto-char (point-min))
  287.            (re-search-forward mail-header-separator)
  288.            (beginning-of-line)
  289.            (next-line 5)
  290.            (insert "--" (mime-primary-boundary) "\n")
  291.            (insert "Content-type: text/plain\n")
  292.            (insert "\n"))
  293.          (if mime-virgin-message
  294.              (backward-delete-char 1)))))))
  295.  
  296. (defun mime-include-binary-file (filename content-type)
  297.   "Include a binary file at point in a MIME message.  Encode it
  298. in base64 mode."
  299.   (mime-mimify-message)
  300.   (push-mark)
  301.   (insert "--" (mime-primary-boundary) "\n")
  302.   (insert "Content-type: " content-type "\n")
  303.   (insert "Content-Transfer-Encoding: base64\n")
  304.   (insert "\n")
  305.   (let ((start (point)) end)
  306.     (next-line 1)
  307.     (save-excursion
  308.       (next-line -1)
  309.       (insert-file filename))
  310.     (setq end (point))
  311.     (shell-command-on-region start end "mmencode" t)
  312.     (setq end (point))
  313.     (if mime-use-selective-display
  314.         (mime-hide-region start (- end 1) t))
  315.     (insert "\n")
  316.     (insert "--" (mime-primary-boundary) "\n")
  317.     (insert "Content-type: text/plain\n")
  318.     (insert "\n\n")
  319.     (next-line -1)))
  320.  
  321. (defun mime-include-nonbinary-file (filename content-type)
  322.   "Include a nonbinary file at point in a MIME message.  Encode it
  323. in quoted-printable mode."
  324.   (mime-mimify-message)
  325.   (push-mark)
  326.   (insert "--" (mime-primary-boundary) "\n")
  327.   (insert "Content-type: " content-type "\n")
  328.   (insert "Content-Transfer-Encoding: quoted-printable\n")
  329.   (insert "\n")
  330.   (let ((start (point)) end)
  331.     (next-line 1)
  332.     (save-excursion
  333.       (next-line -1)
  334.       (insert-file filename))
  335.     (setq end (point))
  336.     (shell-command-on-region start end "mmencode -q" t)
  337.     (setq end (point))
  338.     (insert "\n")
  339.     (insert "--" (mime-primary-boundary) "\n")
  340.     (insert "Content-type: text/plain\n")
  341.     (insert "\n\n")
  342.     (next-line -1)))
  343.  
  344. (defun mime-include-external (site directory name content-type description 
  345.                                    access-type)
  346.   "Include an external pointer in a MIME message."
  347.   (mime-mimify-message)
  348.   (insert "--" (mime-primary-boundary) "\n")
  349.   (insert "Content-type: message/external-body;\n")
  350.   (insert "\taccess-type=\"" access-type "\";\n")
  351.   (insert "\tsite=\"" site "\";\n")
  352.   (insert "\tdirectory=\"" directory "\";\n")
  353.   (insert "\tname=\"" name "\"\n")
  354.   (insert "Content-description: " description "\n")
  355.   (insert "\n")
  356.   (insert "Content-type: " content-type "\n")
  357.   (insert "\n")
  358.   (insert "\n")
  359.   (insert "--" (mime-primary-boundary) "\n")
  360.   (insert "Content-type: text/plain\n")
  361.   (insert "\n"))
  362.  
  363. (defun mime-include-external-anonftp (site directory name content-type 
  364.                                            description)
  365.   "Include an external pointer (anonymous FTP) in a MIME message."
  366.   (interactive "sFTP site: \nsRemote directory name: \nsRemote filename: \nsContent type: \nsDescription: ")
  367.   (mime-include-external site directory name content-type description "anon-ftp"))
  368.  
  369. (defun mime-include-external-ftp (site directory name content-type description)
  370.   "Include an external pointer (regular FTP) in a MIME message."
  371.   (interactive "sFTP site: \nsRemote directory name: \nsRemote filename: \nsContent type: \nsDescription: ")
  372.   (mime-include-external site directory name content-type description "ftp"))
  373.  
  374. (defun mime-include-xwd-dump ()
  375.   "Run xwd and include the results in a MIME message."
  376.   (interactive)
  377.   (mime-mimify-message)
  378.   (push-mark)
  379.   (insert "--" (mime-primary-boundary) "\n")
  380.   (insert "Content-type: image/x-xwd\n")
  381.   (insert "Content-Transfer-Encoding: base64\n")
  382.   (insert "\n")
  383.   (let ((start (point)) end)
  384.     (next-line 1)
  385.     (save-excursion
  386.       (next-line -1)
  387.       (shell-command mime-xwd-command t))
  388.     (setq end (point))
  389.     (shell-command-on-region start end "mmencode" t)
  390.     (setq end (point))
  391.     (insert "\n")
  392.     (insert "--" (mime-primary-boundary) "\n")
  393.     (insert "Content-type: text/plain\n")
  394.     (insert "\n\n")
  395.     (next-line -1)))
  396.  
  397. (defun mime-grab-audio-snippet ()
  398.   (let ((audio-process))
  399.     (setq audio-process 
  400.           (start-process "snippet" "snippet" 
  401.                          "recordaiff" "-n" "1" "-s" "8" "-r" "8000"
  402.                          "/tmp/fooblatz.aiff"))
  403.     ;; Quick hack to make Emacs sit until recording is done.
  404.     (y-or-n-p "Press y or n when finished: ")
  405.     (interrupt-process "snippet")
  406.     ;; Wait until recordaiff has written data to disk. */
  407.     (while (eq (process-status "snippet") 'run)
  408.       (message "Waiting...")
  409.       (sleep-for 1))
  410.     ;; Kill off recordaiff and our buffer.
  411.     (delete-process "snippet")
  412.     (kill-buffer "snippet")
  413.     ;; Remove the old mulaw file and do the conversion.
  414.     (shell-command "rm -r /tmp/fooblatz")
  415.     (shell-command 
  416.      "sfconvert /tmp/fooblatz.aiff /tmp/fooblatz -o mulaw")))
  417.  
  418. (defun mime-include-audio-snippet ()
  419.   "Record a snippet of audio in a MIME message.  This will only work
  420. on SGI IRIS Indigo's and PI/35's."
  421.   (interactive)
  422.   (mime-mimify-message)
  423.   (push-mark)
  424.   (insert "--" (mime-primary-boundary) "\n")
  425.   (insert "Content-type: audio/basic\n")
  426.   (insert "Content-Transfer-Encoding: base64\n")
  427.   (insert "\n")
  428.   (let ((start (point)) end)
  429.     (next-line 1)
  430.     (save-excursion
  431.       (next-line -1)
  432.       (mime-grab-audio-snippet)
  433.       (insert-file "/tmp/fooblatz"))
  434.     (setq end (point))
  435.     (shell-command-on-region start end "mmencode" t)
  436.     (setq end (point))
  437.     (insert "\n")
  438.     (insert "--" (mime-primary-boundary) "\n")
  439.     (insert "Content-type: text/plain\n")
  440.     (insert "\n\n")
  441.     (next-line -1)))
  442.  
  443. (defun mime-include-gif (filename)
  444.   "Include a GIF file."
  445.   (interactive "fGIF image filename: ")
  446.   (mime-include-binary-file filename "image/gif"))
  447. (defun mime-include-jpeg (filename)
  448.   "Include a JPEG file."
  449.   (interactive "fJPEG image filename: ")
  450.   (mime-include-binary-file filename "image/jpeg"))
  451. (defun mime-include-audio (filename)
  452.   "Include an audio file."
  453.   (interactive "fAudio filename: ")
  454.   (mime-include-binary-file filename "audio/basic"))
  455. (defun mime-include-postscript (filename)
  456.   "Include a PostScript file."
  457.   (interactive "fPostScript filename: ")
  458.   (mime-include-nonbinary-file filename "application/postscript"))
  459. (defun mime-include-raw-binary (filename content-type)
  460.   "Include a raw binary file."
  461.   (interactive "fRaw binary filename: \nsContent type (RET for default): ")
  462.   (if (string= content-type "")
  463.       (setq content-type "application/octet-stream"))
  464.   (mime-include-binary-file filename content-type))
  465.  
  466. ;;; Add functions to basic mail mode.
  467. (define-key mail-mode-map "\C-cm" 'mime-mimify-message)
  468. (define-key mail-mode-map "\C-cg" 'mime-include-gif)
  469. (define-key mail-mode-map "\C-cj" 'mime-include-jpeg)
  470. (define-key mail-mode-map "\C-ca" 'mime-include-audio)
  471. (define-key mail-mode-map "\C-cp" 'mime-include-postscript)
  472. (define-key mail-mode-map "\C-cr" 'mime-include-raw-binary)
  473. (define-key mail-mode-map "\C-cx" 'mime-include-xwd-dump)
  474. (define-key mail-mode-map "\C-ce" 'mime-include-external-anonftp)
  475. (define-key mail-mode-map "\C-cf" 'mime-include-external-ftp)
  476. (define-key mail-mode-map "\C-cs" 'mime-include-audio-snippet)
  477.  
  478. ;;; Add functions to MH letter mode.
  479. (if (boundp 'mh-letter-mode-map)
  480.     (if (or (not (boundp 'mh-letter-mode-mime-map)) 
  481.             (not mh-letter-mode-mime-map))
  482.         (progn
  483.           (setq mh-letter-mode-mime-map (make-sparse-keymap))
  484.           (define-key mh-letter-mode-map "\C-c\C-m" mh-letter-mode-mime-map)
  485.           (define-key mh-letter-mode-mime-map "m" 'mime-mimify-message)
  486.           (define-key mh-letter-mode-mime-map "g" 'mime-include-gif)
  487.           (define-key mh-letter-mode-mime-map "j" 'mime-include-jpeg)
  488.           (define-key mh-letter-mode-mime-map "a" 'mime-include-audio)
  489.           (define-key mh-letter-mode-mime-map "p" 'mime-include-postscript)
  490.           (define-key mh-letter-mode-mime-map "r" 'mime-include-raw-binary)
  491.           (define-key mh-letter-mode-mime-map "x" 'mime-include-xwd-dump)
  492.           (define-key mh-letter-mode-mime-map "e" 
  493.             'mime-include-external-anonftp)
  494.           (define-key mh-letter-mode-mime-map "f" 
  495.             'mime-include-external-ftp)
  496.           (define-key mh-letter-mode-mime-map "s"
  497.             'mime-include-audio-snippet))))
  498.  
  499. ;;; -------------------------------- Menubar ---------------------------------
  500.  
  501. (defvar mime-running-lemacs (string-match "Lucid" emacs-version)
  502.   "Non-nil if running Lucid Emacs.")
  503.  
  504. ;; All we do at the moment is replace the popup menu defined in
  505. ;; Lucid Emacs 19.3's sendmail.el.
  506. (if mime-running-lemacs
  507.     (progn
  508.       (setq mail-mode-menu
  509.         '("Mail Mode"
  510.           "Sending Mail:"
  511.           "----"
  512.           ["Send and Exit"        mail-send-and-exit        t]
  513.           ["Send Mail"            mail-send            t]
  514.           ["Sent Via"            mail-sent-via            t]
  515.           "----"
  516.           "Go to Field:"
  517.           "----"
  518.           ["To:"            mail-to                t]
  519.           ["Subject:"            mail-subject            t]
  520.           ["CC:"            mail-cc                t]
  521.           ["BCC:"            mail-bcc            t]
  522.           ["Text"            mail-text            t]
  523.           "----"
  524.           "Miscellaneous Commands:"
  525.           "----"
  526.           ["Yank Original"        mail-yank-original        t]
  527.           ["Fill Yanked Message"    mail-fill-yanked-message    t]
  528.           ["Insert Signature"        mail-signature            t]
  529.           "----"
  530.           "MIME Inclusions:"
  531.           "----"
  532.           ["Include GIF File"           mime-include-gif                t]
  533.           ["Include JPEG File"          mime-include-jpeg               t]
  534.           ["Include Audio File"         mime-include-audio              t]
  535.           ["Include PostScript File"    mime-include-postscript         t]
  536.           ["Include XWD Dump"           mime-include-xwd-dump           t]
  537.           ["Include Raw Binary File"    mime-include-raw-binary         t]
  538.           ["Include External AnonFTP"   mime-include-external-anonftp   t]
  539.           ["Include External FTP"       mime-include-external-ftp       t]
  540.           "----"
  541.           ["Abort" kill-buffer t]
  542.           ))))
  543.  
  544. ;;; ----------------------------- New mail-send ------------------------------
  545.  
  546. ;; If we're not running Lemacs, pop in a new mail-send routine.
  547. (if (not mime-running-lemacs)
  548.     (defun mail-send ()
  549.       "Send the message in the current buffer.
  550. If  mail-interactive  is non-nil, wait for success indication
  551. or error messages, and inform user.
  552. Otherwise any failure is reported in a message back to
  553. the user from the mailer."
  554.       (interactive)
  555.       (message "Sending...")
  556.       (run-hooks 'mail-send-hook)
  557.       (funcall send-mail-function)
  558.       (set-buffer-modified-p nil)
  559.       (delete-auto-save-file-if-necessary)
  560.       (message "Sending...done")))
  561.  
  562. ;;; --------------------------------- Hooks ----------------------------------
  563.  
  564. ;; Author: Daniel LaLiberte (liberte@cs.uiuc.edu).
  565. (defun mime-postpend-unique-hook (hook-var hook-function)
  566.   "Postpend HOOK-VAR with HOOK-FUNCTION, if it is not already an element.
  567. hook-var's value may be a single function or a list of functions."
  568.   (if (boundp hook-var)
  569.       (let ((value (symbol-value hook-var)))
  570.         (if (and (listp value) (not (eq (car value) 'lambda)))
  571.             (and (not (memq hook-function value))
  572.                  (set hook-var (append value (list hook-function))))
  573.           (and (not (eq hook-function value))
  574.                (set hook-var (append value (list hook-function))))))
  575.     (set hook-var (list hook-function))))
  576.  
  577. (defun mime-unfrob-selective-display ()
  578.   "Turn off selective display throughout this buffer."
  579.   (if mime-use-selective-display
  580.       (progn
  581.         (message "Unfrobbing selective-display...")
  582.         (mime-hide-region (point-min) (point-max) nil))))
  583.  
  584. ;; Before the message is sent, remove the selective display crap.
  585. (mime-postpend-unique-hook 'mail-send-hook 'mime-unfrob-selective-display)
  586.  
  587. --
  588. Marc Andreessen
  589. Software Development Group
  590. National Center for Supercomputing Applications
  591. marca@ncsa.uiuc.edu
  592.  
  593.