;;; emh.el --- MIME extender for mh-e ;; Copyright (C) 1995,1996,1997,1998,2000 Free Software Foundation, Inc. ;; Author: MORIOKA Tomohiko ;; OKABE Yasuo ;; Maintainer: MORIOKA Tomohiko ;; Created: 1993/11/21 ;; Renamed: 1993/11/27 from mh-e-mime.el ;; Renamed: 1997/02/21 from tm-mh-e.el ;; Keywords: MH, MIME, multimedia, encoded-word, multilingual, mail ;; This file is part of emh. ;; 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Code: (require 'mh-e) (require 'alist) (require 'mime-view) ;;; @ version ;;; (defconst emh-version "1.14.1") ;;; @ variable ;;; (defgroup emh nil "MIME Extension for mh-e" :group 'mime :group 'mh) (defcustom emh-automatic-mime-preview t "*If non-nil, show MIME processed message." :group 'emh :type 'boolean) (defcustom emh-decode-encoded-word t "*If non-nil, decode encoded-word when it is not MIME preview mode." :group 'emh :type 'boolean) (defcustom emh-icon-directory (if (fboundp 'locate-data-directory) (locate-data-directory "emh") (let ((icons (expand-file-name "emh/icons/" data-directory))) (if (file-directory-p icons) icons))) "*Directory to load the icon files from, or nil if none." :group 'emh :type '(choice (const :tag "none" nil) string)) ;;; @ functions ;;; (defsubst emh-raw-buffer (folder-buffer) (concat "article-" (if (bufferp folder-buffer) (buffer-name folder-buffer) folder-buffer))) (defun mh-display-msg (msg-num folder &optional show-buffer mode) "Display message number MSG-NUM of FOLDER. This function uses `mime-view-mode' if MODE is not nil. If MODE is nil, `emh-automatic-mime-preview' is used as default value." (or mode (setq mode emh-automatic-mime-preview) ) ;; Display message NUMBER of FOLDER. ;; Sets the current buffer to the show buffer. (set-buffer folder) (or show-buffer (setq show-buffer mh-show-buffer)) ;; Bind variables in folder buffer in case they are local (let ((msg-filename (mh-msg-filename msg-num))) (if (not (file-exists-p msg-filename)) (error "Message %d does not exist" msg-num)) (set-buffer show-buffer) (cond ((not (equal msg-filename buffer-file-name)) ;; Buffer does not yet contain message. (clear-visited-file-modtime) (unlock-buffer) (setq buffer-file-name nil) ; no locking during setup (setq buffer-read-only nil) (erase-buffer) (if mode (let* ((aname (emh-raw-buffer folder)) (abuf (get-buffer aname))) (if abuf (progn (set-buffer abuf) (setq buffer-read-only nil) (erase-buffer)) (setq abuf (get-buffer-create aname)) (set-buffer abuf) (set-buffer-multibyte nil)) (8bit-insert-encoded-file msg-filename) (set-buffer-modified-p nil) (setq buffer-read-only t) (setq buffer-file-name msg-filename) (mh-show-mode) (mime-display-message (mime-open-entity 'buffer aname) (concat "show-" folder)) (goto-char (point-min))) (let ((clean-message-header mh-clean-message-header) (invisible-headers mh-invisible-headers) (visible-headers mh-visible-headers)) ;; 1995/9/21 ;; modified by ARIURA ;; to support mhl. (if mhl-formfile (mh-exec-lib-cmd-output "mhl" "-nobell" "-noclear" (if (stringp mhl-formfile) (list "-form" mhl-formfile)) msg-filename) (insert-file-contents msg-filename)) ;; end (goto-char (point-min)) (cond (clean-message-header (mh-clean-msg-header (point-min) invisible-headers visible-headers) (goto-char (point-min))) (t (mh-start-of-uncleaned-message))) (if emh-decode-encoded-word (mime-decode-header-in-buffer)) (set-buffer-modified-p nil) (setq buffer-read-only t) (setq buffer-file-name msg-filename) (mh-show-mode) )) (or (eq buffer-undo-list t) ;don't save undo info for prev msgs (setq buffer-undo-list nil)) ;;; Added by itokon (02/19/96) (setq buffer-file-name msg-filename) ;;; (set-mark nil) (setq mode-line-buffer-identification (list (format mh-show-buffer-mode-line-buffer-id folder msg-num))) (set-buffer folder) (setq mh-showing-with-headers nil))))) (defun emh-view-message (&optional msg) "MIME decode and play this message." (interactive) (if (or (null emh-automatic-mime-preview) (null (get-buffer mh-show-buffer)) (save-excursion (set-buffer mh-show-buffer) (not (eq major-mode 'mime-view-mode)) )) (let ((emh-automatic-mime-preview t)) (mh-invalidate-show-buffer) (mh-show-msg msg) )) (pop-to-buffer mh-show-buffer) ) (defun emh-toggle-decoding-mode (arg) "Toggle MIME processing mode. With arg, turn MIME processing on if arg is positive." (interactive "P") (setq emh-automatic-mime-preview (if (null arg) (not emh-automatic-mime-preview) arg)) (let ((raw-buffer (emh-raw-buffer (current-buffer)))) (if (get-buffer raw-buffer) (kill-buffer raw-buffer) )) (mh-invalidate-show-buffer) (mh-show (mh-get-msg-num t)) ) (defun emh-show (&optional message) (interactive) (mh-invalidate-show-buffer) (mh-show message) ) (defun emh-header-display () (interactive) (mh-invalidate-show-buffer) (let (mime-view-ignored-field-list mime-view-visible-field-list emh-decode-encoded-word) (mh-header-display) )) (defun emh-raw-display () (interactive) (mh-invalidate-show-buffer) (let (emh-automatic-mime-preview emh-decode-encoded-word) (mh-header-display) )) (defun emh-burst-multipart/digest () "Burst apart the current message, which should be a multipart/digest. The message is replaced by its table of contents and the letters from the digest are inserted into the folder after that message." (interactive) (let ((digest (mh-get-msg-num t))) (mh-process-or-undo-commands mh-current-folder) (mh-set-folder-modified-p t) ; lock folder while bursting (message "Bursting digest...") (mh-exec-cmd "mhn" "-store" mh-current-folder digest) (mh-scan-folder mh-current-folder (format "%d-last" mh-first-msg-num)) (message "Bursting digest...done") )) ;;; @ for mime-view ;;; (defvar emh-display-header-hook (if window-system '(emh-highlight-header)) "Hook for header filtering.") (autoload 'emh-highlight-header "emh-face") (defun emh-header-presentation-method (entity situation) (mime-insert-header entity mime-view-ignored-field-list mime-view-visible-field-list) (run-hooks 'emh-display-header-hook) ) (set-alist 'mime-header-presentation-method-alist 'mh-show-mode #'emh-header-presentation-method) (defun emh-quitting-method () (let ((buf (current-buffer))) (mime-maybe-hide-echo-buffer) (pop-to-buffer (let ((name (buffer-name buf))) (substring name 5) )) (if (not emh-automatic-mime-preview) (mh-invalidate-show-buffer) ) (mh-show (mh-get-msg-num t)) )) (set-alist 'mime-preview-quitting-method-alist 'mh-show-mode #'emh-quitting-method) (defun emh-following-method (buf) (save-excursion (set-buffer buf) (goto-char (point-max)) (setq mh-show-buffer buf) (apply (function mh-send) (std11-field-bodies '("From" "cc" "Subject") "")) (setq mh-sent-from-folder buf) (setq mh-sent-from-msg 1) (let ((last (point))) (mh-yank-cur-msg) (goto-char last) ))) (set-alist 'mime-preview-following-method-alist 'mh-show-mode #'emh-following-method) ;;; @@ for mime-partial ;;; (defun emh-request-partial-message () (let ((msg-filename (mh-msg-filename (mh-get-msg-num t))) (show-buffer mh-show-buffer) (coding-system-for-read 'raw-text)) (set-buffer (get-buffer-create " *Partial Article*")) (erase-buffer) (setq mime-preview-buffer show-buffer) (insert-file-contents msg-filename) (mime-parse-buffer) )) (defun emh-get-folder-buffer () (let ((buffer-name (buffer-name (current-buffer)))) (and (or (string-match "^article-\\(.+\\)$" buffer-name) (string-match "^show-\\(.+\\)$" buffer-name)) (substring buffer-name (match-beginning 1) (match-end 1)) ))) (autoload 'mime-combine-message/partial-pieces-automatically "mime-partial" "Internal method to combine message/partial messages automatically.") (mime-add-condition 'action '((type . message)(subtype . partial) (major-mode . mh-show-mode) (method . mime-combine-message/partial-pieces-automatically) (summary-buffer-exp . (emh-get-folder-buffer)) (request-partial-message-method . emh-request-partial-message) )) ;;; @ set up ;;; (define-key mh-folder-mode-map "v" (function emh-view-message)) (define-key mh-folder-mode-map "\et" (function emh-toggle-decoding-mode)) (define-key mh-folder-mode-map "." (function emh-show)) (define-key mh-folder-mode-map "," (function emh-header-display)) (define-key mh-folder-mode-map "\e," (function emh-raw-display)) (define-key mh-folder-mode-map "\C-c\C-b" (function emh-burst-multipart/digest)) (defun emh-summary-before-quit () (let ((buf (get-buffer mh-show-buffer))) (if buf (let ((the-buf (current-buffer))) (switch-to-buffer buf) (if (and mime-preview-buffer (setq buf (get-buffer mime-preview-buffer)) ) (progn (switch-to-buffer the-buf) (kill-buffer buf) ) (switch-to-buffer the-buf) ) )))) (add-hook 'mh-before-quit-hook (function emh-summary-before-quit)) ;;; @ for BBDB ;;; (eval-after-load "bbdb" '(require 'mime-bbdb)) ;;; @ Toolbar (if (and (not (featurep 'xemacs)) (boundp 'emacs-major-version) (>= emacs-major-version 21)) (require 'emh-e21)) ;;; @ end ;;; (provide 'emh) (run-hooks 'emh-load-hook) ;;; emh.el ends here