X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=mime-view.el;h=2a30e18c73bddf2ad5d57dd38c2b5082f14b428a;hb=39725d24b7906f6cc7b92869604ae1372c8a28a8;hp=3322e32329712ccfaaeff61a3310f9058c12d3bb;hpb=536d5c7b4ffecc9615ac819cd71581add2d1acfd;p=elisp%2Fsemi.git diff --git a/mime-view.el b/mime-view.el index 3322e32..2a30e18 100644 --- a/mime-view.el +++ b/mime-view.el @@ -1,6 +1,6 @@ ;;; mime-view.el --- interactive MIME viewer for GNU Emacs -;; Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc. +;; Copyright (C) 1995,1996,1997,1998,1999 Free Software Foundation, Inc. ;; Author: MORIOKA Tomohiko ;; Created: 1994/07/13 @@ -8,7 +8,7 @@ ;; Renamed: 1997/02/19 from tm-view.el ;; Keywords: MIME, multimedia, mail, news -;; This file is part of SEMI (Sophisticated Emacs MIME Interfaces). +;; This file is part of SEMI (Sample of Elastic MIME Interfaces). ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as @@ -27,6 +27,7 @@ ;;; Code: +(require 'emu) (require 'mime) (require 'semi-def) (require 'calist) @@ -37,11 +38,11 @@ ;;; @ version ;;; -(defconst mime-view-version-string - `,(concat (car mime-user-interface-version) " MIME-View " - (mapconcat #'number-to-string - (cddr mime-user-interface-version) ".") - " (" (cadr mime-user-interface-version) ")")) +(defconst mime-view-version + (concat (mime-product-name mime-user-interface-product) " MIME-View " + (mapconcat #'number-to-string + (mime-product-version mime-user-interface-product) ".") + " (" (mime-product-code-name mime-user-interface-product) ")")) ;;; @ variables @@ -138,37 +139,87 @@ mother-buffer." ;;; @ entity information ;;; -(defun mime-entity-situation (entity) +(defun mime-entity-situation (entity &optional situation) "Return situation of ENTITY." - (append (or (mime-entity-content-type entity) - (make-mime-content-type 'text 'plain)) - (let ((d (mime-entity-content-disposition entity))) - (cons (cons 'disposition-type - (mime-content-disposition-type d)) - (mapcar (function - (lambda (param) - (let ((name (car param))) - (cons (cond ((string= name "filename") - 'filename) - ((string= name "creation-date") - 'creation-date) - ((string= name "modification-date") - 'modification-date) - ((string= name "read-date") - 'read-date) - ((string= name "size") - 'size) - (t (cons 'disposition (car param)))) - (cdr param))))) - (mime-content-disposition-parameters d)) - )) - (list (cons 'encoding (mime-entity-encoding entity)) - (cons 'major-mode - (save-excursion - (set-buffer (mime-entity-buffer entity)) - major-mode))) - )) + (let (rest param name) + ;; Content-Type + (unless (assq 'type situation) + (setq rest (or (mime-entity-content-type entity) + (make-mime-content-type 'text 'plain)) + situation (cons (car rest) situation) + rest (cdr rest)) + ) + (unless (assq 'subtype situation) + (or rest + (setq rest (or (cdr (mime-entity-content-type entity)) + '((subtype . plain))))) + (setq situation (cons (car rest) situation) + rest (cdr rest)) + ) + (while rest + (setq param (car rest)) + (or (assoc (car param) situation) + (setq situation (cons param situation))) + (setq rest (cdr rest))) + + ;; Content-Disposition + (setq rest nil) + (unless (assq 'disposition-type situation) + (setq rest (mime-entity-content-disposition entity)) + (if rest + (setq situation (cons (cons 'disposition-type + (mime-content-disposition-type rest)) + situation) + rest (mime-content-disposition-parameters rest)) + )) + (while rest + (setq param (car rest) + name (car param)) + (if (cond ((string= name "filename") + (if (assq 'filename situation) + nil + (setq name 'filename))) + ((string= name "creation-date") + (if (assq 'creation-date situation) + nil + (setq name 'creation-date))) + ((string= name "modification-date") + (if (assq 'modification-date situation) + nil + (setq name 'modification-date))) + ((string= name "read-date") + (if (assq 'read-date situation) + nil + (setq name 'read-date))) + ((string= name "size") + (if (assq 'size situation) + nil + (setq name 'size))) + (t (setq name (cons 'disposition name)) + (if (assoc name situation) + nil + name))) + (setq situation + (cons (cons name (cdr param)) + situation))) + (setq rest (cdr rest))) + + ;; Content-Transfer-Encoding + (or (assq 'encoding situation) + (setq situation + (cons (cons 'encoding (or (mime-entity-encoding entity) + "7bit")) + situation))) + ;; major-mode + (or (assq 'major-mode situation) + (setq situation + (cons (cons 'major-mode + (with-current-buffer (mime-entity-buffer entity) + major-mode)) + situation))) + + situation)) (defun mime-view-entity-title (entity) (or (mime-read-field 'Content-Description entity) @@ -255,9 +306,13 @@ Please redefine this function if you want to change default setting." num subject access-type (cdr server)) (let ((site (cdr (assoc "site" params))) (dir (cdr (assoc "directory" params))) + (url (cdr (assoc "url" params))) ) - (format "%s %s ([%s] %s:%s)" - num subject access-type site dir) + (if url + (format "%s %s ([%s] %s)" + num subject access-type url) + (format "%s %s ([%s] %s:%s)" + num subject access-type site dir)) ))) ) (t @@ -294,15 +349,15 @@ SYMBOL must be major mode in raw-buffer or t. t means default. Interface of FUNCTION must be (ENTITY SITUATION).") (defvar mime-view-ignored-field-list - '(".*Received" ".*Path" ".*Id" "References" - "Replied" "Errors-To" - "Lines" "Sender" ".*Host" "Xref" - "Content-Type" "Precedence" - "Status" "X-VM-.*") + '(".*Received:" ".*Path:" ".*Id:" "^References:" + "^Replied:" "^Errors-To:" + "^Lines:" "^Sender:" ".*Host:" "^Xref:" + "^Content-Type:" "^Precedence:" + "^Status:" "^X-VM-.*:") "All fields that match this list will be hidden in MIME preview buffer. Each elements are regexp of field-name.") -(defvar mime-view-visible-field-list '("Dnas.*" "Message-Id") +(defvar mime-view-visible-field-list '("^Dnas.*:" "^Message-Id:") "All fields that match this list will be displayed in MIME preview buffer. Each elements are regexp of field-name.") @@ -313,6 +368,8 @@ Each elements are regexp of field-name.") ;;; @@@ predicate function ;;; +(in-calist-package 'mime-view) + (defun mime-calist::field-match-method-as-default-rule (calist field-type field-value) (let ((s-field (assq field-type calist))) @@ -420,9 +477,38 @@ Each elements are regexp of field-name.") ;;; @@@ entity presentation ;;; -(autoload 'mime-display-text/plain "mime-text") -(autoload 'mime-display-text/enriched "mime-text") -(autoload 'mime-display-text/richtext "mime-text") +(defun mime-display-text/plain (entity situation) + (save-restriction + (narrow-to-region (point-max)(point-max)) + (mime-insert-text-content entity) + (run-hooks 'mime-text-decode-hook) + (goto-char (point-max)) + (if (not (eq (char-after (1- (point))) ?\n)) + (insert "\n") + ) + (mime-add-url-buttons) + (run-hooks 'mime-display-text/plain-hook) + )) + +(defun mime-display-text/richtext (entity situation) + (save-restriction + (narrow-to-region (point-max)(point-max)) + (mime-insert-text-content entity) + (run-hooks 'mime-text-decode-hook) + (let ((beg (point-min))) + (remove-text-properties beg (point-max) '(face nil)) + (richtext-decode beg (point-max)) + ))) + +(defun mime-display-text/enriched (entity situation) + (save-restriction + (narrow-to-region (point-max)(point-max)) + (mime-insert-text-content entity) + (run-hooks 'mime-text-decode-hook) + (let ((beg (point-min))) + (remove-text-properties beg (point-max) '(face nil)) + (enriched-decode beg (point-max)) + ))) (defvar mime-view-announcement-for-message/partial (if (and (>= emacs-major-version 19) window-system) @@ -466,10 +552,11 @@ Each elements are regexp of field-name.") MEDIA-TYPE must be (TYPE . SUBTYPE), TYPE or t. t means default." :group 'mime-view :type '(repeat (cons (choice :tag "Media-Type" - (item :tag "Type/Subtype" - (cons symbol symbol)) - (item :tag "Type" symbol) - (item :tag "Default" t)) + (cons :tag "Type/Subtype" + (symbol :tag "Primary-type") + (symbol :tag "Subtype")) + (symbol :tag "Type") + (const :tag "Default" t)) integer))) (defun mime-display-multipart/alternative (entity situation) @@ -650,9 +737,10 @@ MEDIA-TYPE must be (TYPE . SUBTYPE), TYPE or t. t means default." (setq preview-buffer (current-buffer))) (let* ((raw-buffer (mime-entity-buffer entity)) (start (mime-entity-point-min entity)) - e nb ne) + e nb ne nhb nbb) (set-buffer raw-buffer) (goto-char start) + (in-calist-package 'mime-view) (or situation (setq situation (or (ctree-match-calist mime-preview-condition @@ -677,19 +765,18 @@ MEDIA-TYPE must be (TYPE . SUBTYPE), TYPE or t. t means default." (mime-view-insert-entity-button entity) )) (when header-is-visible + (setq nhb (point)) (if header-presentation-method (funcall header-presentation-method entity situation) - (mime-insert-decoded-header entity - mime-view-ignored-field-list - mime-view-visible-field-list - (if (mime-entity-cooked-p entity) - nil - default-mime-charset)) - ) + (mime-insert-header entity + mime-view-ignored-field-list + mime-view-visible-field-list)) + (run-hooks 'mime-display-header-hook) + (put-text-property nhb (point-max) 'mime-view-entity-header entity) (goto-char (point-max)) (insert "\n") - (run-hooks 'mime-display-header-hook) ) + (setq nbb (point)) (cond (children) ((functionp body-presentation-method) (funcall body-presentation-method entity situation) @@ -708,6 +795,7 @@ MEDIA-TYPE must be (TYPE . SUBTYPE), TYPE or t. t means default." (setq ne (point-max)) (widen) (put-text-property nb ne 'mime-view-entity entity) + (put-text-property nbb ne 'mime-view-entity-body entity) (goto-char ne) (if children (if (functionp body-presentation-method) @@ -733,7 +821,7 @@ MEDIA-TYPE must be (TYPE . SUBTYPE), TYPE or t. t means default." ) "Menu for MIME Viewer") -(cond (running-xemacs +(cond ((featurep 'xemacs) (defvar mime-view-xemacs-popup-menu (cons mime-view-menu-title (mapcar (function @@ -803,7 +891,7 @@ MEDIA-TYPE must be (TYPE . SUBTYPE), TYPE or t. t means default." (define-key mime-view-mode-map [backspace] (function mime-preview-scroll-down-entity)) (if (functionp default) - (cond (running-xemacs + (cond ((featurep 'xemacs) (set-keymap-default-binding mime-view-mode-map default) ) (t @@ -814,7 +902,7 @@ MEDIA-TYPE must be (TYPE . SUBTYPE), TYPE or t. t means default." (define-key mime-view-mode-map mouse-button-2 (function mime-button-dispatcher)) ) - (cond (running-xemacs + (cond ((featurep 'xemacs) (define-key mime-view-mode-map mouse-button-3 (function mime-view-xemacs-popup-menu)) ) @@ -852,8 +940,20 @@ MEDIA-TYPE must be (TYPE . SUBTYPE), TYPE or t. t means default." (defvar mime-view-redisplay nil) +;;;###autoload (defun mime-display-message (message &optional preview-buffer mother default-keymap-or-function) + "View MESSAGE in MIME-View mode. + +Optional argument PREVIEW-BUFFER specifies the buffer of the +presentation. It must be either nil or a name of preview buffer. + +Optional argument MOTHER specifies mother-buffer of the preview-buffer. + +Optional argument DEFAULT-KEYMAP-OR-FUNCTION is nil, keymap or +function. If it is a keymap, keymap of MIME-View mode will be added +to it. If it is a function, it will be bound as default binding of +keymap of MIME-View mode." (mime-maybe-hide-echo-buffer) (let ((win-conf (current-window-configuration)) (raw-buffer (mime-entity-buffer message))) @@ -899,6 +999,7 @@ MEDIA-TYPE must be (TYPE . SUBTYPE), TYPE or t. t means default." ))))) ))) +;;;###autoload (defun mime-view-buffer (&optional raw-buffer preview-buffer mother default-keymap-or-function representation-type) @@ -911,7 +1012,7 @@ to it. If it is a function, it will be bound as default binding of keymap of MIME-View mode. Optional argument REPRESENTATION-TYPE is representation-type of message. It must be nil, `binary' or `cooked'. If it is nil, -`binary' is used as default." +`cooked' is used as default." (interactive) (or raw-buffer (setq raw-buffer (current-buffer))) @@ -984,22 +1085,22 @@ button-2 Move to point under the mouse cursor (autoload 'mime-preview-play-current-entity "mime-play" "Play current entity." t) -(defun mime-preview-extract-current-entity () +(defun mime-preview-extract-current-entity (&optional ignore-examples) "Extract current entity into file (maybe). It decodes current entity to call internal or external method as \"extract\" mode. The method is selected from variable `mime-acting-condition'." - (interactive) - (mime-preview-play-current-entity "extract") + (interactive "P") + (mime-preview-play-current-entity ignore-examples "extract") ) -(defun mime-preview-print-current-entity () +(defun mime-preview-print-current-entity (&optional ignore-examples) "Print current entity (maybe). It decodes current entity to call internal or external method as \"print\" mode. The method is selected from variable `mime-acting-condition'." - (interactive) - (mime-preview-play-current-entity "print") + (interactive "P") + (mime-preview-play-current-entity ignore-examples "print") ) @@ -1019,6 +1120,7 @@ It calls following-method selected from variable (let* ((p-beg (previous-single-property-change (point) 'mime-view-entity)) p-end + ph-end (entity-node-id (mime-entity-node-id entity)) (len (length entity-node-id)) ) @@ -1062,6 +1164,12 @@ It calls following-method selected from variable (setq p-end (point-max)) )) )) + (setq ph-end + (previous-single-property-change p-end 'mime-view-entity-header)) + (if (or (null ph-end) + (< ph-end p-beg)) + (setq ph-end p-beg) + ) (let* ((mode (mime-preview-original-major-mode 'recursive)) (new-name (format "%s-%s" (buffer-name) (reverse entity-node-id))) @@ -1072,7 +1180,10 @@ It calls following-method selected from variable (save-excursion (set-buffer (setq new-buf (get-buffer-create new-name))) (erase-buffer) - (insert-buffer-substring the-buf p-beg p-end) + (insert-buffer-substring the-buf ph-end p-end) + (when (= ph-end p-beg) + (goto-char (point-min)) + (insert ?\n)) (goto-char (point-min)) (let ((entity-node-id (mime-entity-node-id entity)) ci str) (while (progn @@ -1091,9 +1202,8 @@ It calls following-method selected from variable (concat "^" (apply (function regexp-or) fields) ":") "")))) - (if (and - (eq (mime-entity-media-type ci) 'message) - (eq (mime-entity-media-subtype ci) 'rfc822)) + (if (and (eq (mime-entity-media-type ci) 'message) + (eq (mime-entity-media-subtype ci) 'rfc822)) nil (if str (insert str) @@ -1121,7 +1231,7 @@ It calls following-method selected from variable )) (setq rest (cdr rest)) )) - (eword-decode-header) + (mime-decode-header-in-buffer) ) (let ((f (cdr (assq mode mime-preview-following-method-alist)))) (if (functionp f) @@ -1186,7 +1296,8 @@ variable `mime-preview-over-to-previous-method-alist'." If there is no previous entity, it calls function registered in variable `mime-preview-over-to-next-method-alist'." (interactive) - (while (null (get-text-property (point) 'mime-view-entity)) + (while (and (not (eobp)) + (null (get-text-property (point) 'mime-view-entity))) (forward-char) ) (let ((point (next-single-property-change (point) 'mime-view-entity)))