tm 7.80.
[elisp/tm.git] / tm-view.el
index 9c88f3a..b66f13d 100644 (file)
@@ -1,32 +1,29 @@
-;;;
 ;;; tm-view.el --- interactive MIME viewer for GNU Emacs
-;;;
-;;; Copyright (C) 1995 Free Software Foundation, Inc.
-;;; Copyright (C) 1994 .. 1996 MORIOKA Tomohiko
-;;;
-;;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
-;;; modified by Steven L. Baur <steve@miranova.com>
-;;; Maintainer: MORIOKA Tomohiko <morioka@jaist.ac.jp>
-;;; Created: 1994/7/13 (1994/8/31 obsolete tm-body.el)
-;;; Version: $Revision: 7.59 $
-;;; Keywords: mail, news, MIME, multimedia
-;;;
-;;; This file is part of tm (Tools for MIME).
-;;;
-;;; 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 This program.  If not, write to the Free Software
-;;; Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-;;;
+
+;; Copyright (C) 1995,1996 Free Software Foundation, Inc.
+
+;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
+;; Created: 1994/7/13 (1994/8/31 obsolete tm-body.el)
+;; Version: $Revision: 7.73 $
+;; Keywords: mail, news, MIME, multimedia
+
+;; This file is part of tm (Tools for MIME).
+
+;; 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 This program; 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 'tl-str)
@@ -45,7 +42,7 @@
 ;;;
 
 (defconst mime-viewer/RCS-ID
-  "$Id: tm-view.el,v 7.59 1996/05/11 16:23:16 morioka Exp $")
+  "$Id: tm-view.el,v 7.73 1996/08/30 16:57:53 morioka Exp $")
 
 (defconst mime-viewer/version (get-version-string mime-viewer/RCS-ID))
 (defconst mime/viewer-version mime-viewer/version)
     "application/octet-stream"
     "application/x-selection" "application/x-comment"))
 
-(defvar mime-viewer/content-subject-omitting-Content-Type-list
+(defvar mime-viewer/content-button-ignored-ctype-list
   '("application/x-selection"))
 
-(defvar mime-viewer/content-subject-showing-Content-Type-list
+(defvar mime-viewer/content-button-visible-ctype-list
   '("application/pgp"))
 
 (defvar mime-viewer/uuencode-encoding-name-list '("x-uue" "x-uuencode"))
@@ -136,7 +133,7 @@ Each elements are regexp of field-name. [tm-view.el]")
          ":"))
 
 (defvar mime-viewer/visible-field-list
-  '("Dnas.*")
+  '("Dnas.*" "Message-Id")
   "All fields that match this list will be displayed in MIME preview buffer.
 Each elements are regexp of field-name. [tm-view.el]")
 
@@ -193,54 +190,69 @@ Each elements are regexp of field-name. [tm-view.el]")
     ))
 
 
-;;; @@ content subject
+;;; @@ content button
 ;;;
 
-(defun mime-viewer/insert-content-subject
-  (rcnum cinfo ctype params subj)
+(defun mime-preview/insert-content-button
+  (rcnum cinfo ctype params subj encoding)
   (save-restriction
     (narrow-to-region (point)(point))
-    (insert
-     (let ((access-type (assoc "access-type" params))
-          (num (or (assoc-value "x-part-number" params)
-                   (if (consp rcnum)
-                       (mapconcat (function
-                                   (lambda (num)
-                                     (format "%s" (1+ num))
-                                     ))
-                                  (reverse rcnum) ".")
-                     "0"))
-               ))
-       (if access-type
-          (let ((server (assoc "server" params)))
-            (setq access-type (cdr access-type))
-            (if server
-                (format "[%s %s ([%s] %s)]\n" num subj
-                        access-type (cdr server))
-              (let ((site (assoc-value "site" params))
-                    (dir (assoc-value "directory" params))
-                    )
-                (format "[%s %s ([%s] %s:%s)]\n" num subj
-                        access-type site dir)
-                )))
-        (format "[%s %s (%s)]\n" num subj ctype)
-        )))
+    (let ((access-type (assoc "access-type" params))
+         (charset (assoc "charset" params))
+         (num (or (assoc-value "x-part-number" params)
+                  (if (consp rcnum)
+                      (mapconcat (function
+                                  (lambda (num)
+                                    (format "%s" (1+ num))
+                                    ))
+                                 (reverse rcnum) ".")
+                    "0"))
+              ))
+      (cond (access-type
+            (let ((server (assoc "server" params)))
+              (setq access-type (cdr access-type))
+              (if server
+                  (insert (format "[%s %s ([%s] %s)]\n" num subj
+                                  access-type (cdr server)))
+                (let ((site (assoc-value "site" params))
+                      (dir (assoc-value "directory" params))
+                      )
+                  (insert (format "[%s %s ([%s] %s:%s)]\n" num subj
+                                  access-type site dir))
+                  )))
+            )
+           (t
+            (insert (concat "[" num " " subj))
+            (let ((rest
+                   (if (setq charset (cdr charset))
+                       (if encoding
+                           (format " <%s; %s (%s)>]\n"
+                                   ctype charset encoding)
+                         (format " <%s; %s>]\n" ctype charset)
+                         )
+                     (format " <%s>]\n" ctype)
+                     )))
+              (if (>= (+ (current-column)(length rest))(window-width))
+                  (setq rest (concat "\n\t" rest))
+                )
+              (insert rest)
+              ))))
     (tm:add-button (point-min)(1- (point-max))
                   (function mime-viewer/play-content))
     ))
 
-(defun mime-viewer/default-content-subject-function
-  (rcnum cinfo ctype params subj)
+(defun mime-preview/default-content-button-function
+  (rcnum cinfo ctype params subj encoding)
   (if (and (consp rcnum)
           (not (member
                 ctype
-                mime-viewer/content-subject-omitting-Content-Type-list)))
-      (mime-viewer/insert-content-subject
-       rcnum cinfo ctype params subj)
+                mime-viewer/content-button-ignored-ctype-list)))
+      (mime-preview/insert-content-button
+       rcnum cinfo ctype params subj encoding)
     ))
 
-(defvar mime-viewer/content-subject-function
-  (function mime-viewer/default-content-subject-function))
+(defvar mime-preview/content-button-function
+  (function mime-preview/default-content-button-function))
 
 
 ;;; @@ content header filter
@@ -287,7 +299,7 @@ Each elements are regexp of field-name. [tm-view.el]")
 ;;; @@ content separator
 ;;;
 
-(defun mime-viewer/default-content-separator (rcnum cinfo ctype params subj)
+(defun mime-preview/default-content-separator (rcnum cinfo ctype params subj)
   (if (and (not (mime-viewer/header-visible-p rcnum cinfo ctype))
           (not (mime-viewer/body-visible-p rcnum cinfo ctype))
           )
@@ -360,7 +372,7 @@ The compressed face will be piped to this command.")
     (goto-char (point-min))
     (if (re-search-forward "^X-Face:[ \t]*" nil t)
        (let ((beg (match-end 0))
-             (end (rfc822/field-end))
+             (end (std11-field-end))
              )
          (call-process-region beg end "sh" nil 0 nil
                               "-c" mime-viewer/x-face-command)
@@ -460,37 +472,34 @@ The compressed face will be piped to this command.")
     (set-buffer obuf)
     (setq nb (point))
     (narrow-to-region nb nb)
-    (funcall mime-viewer/content-subject-function
-            rcnum cinfo ctype params subj)
+    (funcall mime-preview/content-button-function
+            rcnum cinfo ctype params subj encoding)
     (if (mime-viewer/header-visible-p rcnum cinfo ctype)
        (mime-preview/display-header beg he)
       )
-    (set-buffer ibuf)
     (if (and (null rcnum)
             (member
-             ctype mime-viewer/content-subject-showing-Content-Type-list))
+             ctype mime-viewer/content-button-visible-ctype-list))
        (save-excursion
-         (set-buffer obuf)
          (goto-char (point-max))
-         (mime-viewer/insert-content-subject rcnum cinfo ctype params subj)
+         (mime-preview/insert-content-button
+          rcnum cinfo ctype params subj encoding)
          ))
     (cond ((mime-viewer/body-visible-p rcnum cinfo ctype)
-          (mime-viewer/display-body he end obuf
-                                    rcnum cinfo ctype params subj encoding)
+          (mime-preview/display-body he end
+                                     rcnum cinfo ctype params subj encoding)
           )
          ((equal ctype "message/partial")
-          (mime-viewer/display-message/partial obuf)
+          (mime-preview/display-message/partial)
           )
          ((and (null rcnum)
                (null (mime::content-info/children cinfo))
                )
-          (set-buffer obuf)
           (goto-char (point-max))
-          (mime-viewer/insert-content-subject rcnum cinfo ctype params subj)
-          )
-         (t (set-buffer obuf))
-         )
-    (mime-viewer/default-content-separator rcnum cinfo ctype params subj)
+          (mime-preview/insert-content-button
+           rcnum cinfo ctype params subj encoding)
+          ))
+    (mime-preview/default-content-separator rcnum cinfo ctype params subj)
     (prog1
        (progn
          (setq ne (point-max))
@@ -513,23 +522,19 @@ The compressed face will be piped to this command.")
     (run-hooks 'mime-viewer/content-header-filter-hook)
     ))
 
-(defun mime-viewer/display-body (beg end obuf
-                                    rcnum cinfo ctype params subj encoding)
-  (let ((str (buffer-substring beg end))
-       be)
-    (set-buffer obuf)
-    (save-restriction
-      (setq be (point-max))
-      (narrow-to-region be be)
-      (insert str)
-      (let ((f (cdr (or (assoc ctype mime-viewer/content-filter-alist)
-                       (assq t mime-viewer/content-filter-alist)))))
-       (and (functionp f)
-            (funcall f ctype params encoding)
-            )))))
-
-(defun mime-viewer/display-message/partial (obuf)
-  (set-buffer obuf)
+(defun mime-preview/display-body (beg end
+                                     rcnum cinfo ctype params subj encoding)
+  (save-restriction
+    (narrow-to-region (point-max)(point-max))
+    (insert-buffer-substring mime::preview/article-buffer beg end)
+    (let ((f (cdr (or (assoc ctype mime-viewer/content-filter-alist)
+                     (assq t mime-viewer/content-filter-alist)))))
+      (and (functionp f)
+          (funcall f ctype params encoding)
+          )
+      )))
+
+(defun mime-preview/display-message/partial ()
   (save-restriction
     (goto-char (point-max))
     (if (not (search-backward "\n\n" nil t))
@@ -556,8 +561,7 @@ The compressed face will be piped to this command.")
     ))
 
 (defun mime-article/get-subject (param &optional encoding)
-  (or (rfc822/get-field-body "Content-Description")
-      (rfc822/get-field-body "Subject")
+  (or (std11-find-field-body '("Content-Description" "Subject"))
       (let (ret)
        (if (or (and (setq ret (mime/Content-Disposition))
                     (setq ret (assoc "filename" (cdr ret)))
@@ -600,13 +604,12 @@ The compressed face will be piped to this command.")
   (or cinfo
       (setq cinfo mime::article/content-info)
       )
-  (some-element
-   (function
-    (lambda (ci)
-      (equal (mime::content-info/rcnum ci) rcnum)
-      ))
-   (mime/flatten-content-info cinfo)
-   ))
+  (find-if (function
+           (lambda (ci)
+             (equal (mime::content-info/rcnum ci) rcnum)
+             ))
+          (mime/flatten-content-info cinfo)
+          ))
 
 (defun mime-article/cnum-to-cinfo (cn &optional cinfo)
   (or cinfo
@@ -672,85 +675,94 @@ The compressed face will be piped to this command.")
     )
   "Menu for MIME Viewer")
 
-(defvar mime/viewer-mode-map nil)
-(if (null mime/viewer-mode-map)
+(if running-xemacs
     (progn
-      (setq mime/viewer-mode-map (make-keymap))
-      (suppress-keymap mime/viewer-mode-map)
-      (define-key mime/viewer-mode-map
-       "u"        (function mime-viewer/up-content))
-      (define-key mime/viewer-mode-map
-       "p"        (function mime-viewer/previous-content))
-      (define-key mime/viewer-mode-map
-       "n"        (function mime-viewer/next-content))
-      (define-key mime/viewer-mode-map
-       " "        (function mime-viewer/scroll-up-content))
-      (define-key mime/viewer-mode-map
-       "\M- "     (function mime-viewer/scroll-down-content))
-      (define-key mime/viewer-mode-map
-       "\177"     (function mime-viewer/scroll-down-content))
-      (define-key mime/viewer-mode-map
-       "\C-m"     (function mime-viewer/next-line-content))
-      (define-key mime/viewer-mode-map
-       "\C-\M-m"  (function mime-viewer/previous-line-content))
-      (define-key mime/viewer-mode-map
-       "v"        (function mime-viewer/play-content))
-      (define-key mime/viewer-mode-map
-       "e"        (function mime-viewer/extract-content))
-      (define-key mime/viewer-mode-map
-       "\C-c\C-p" (function mime-viewer/print-content))
-      (define-key mime/viewer-mode-map
-       "x"        (function mime-viewer/display-x-face))
-      (define-key mime/viewer-mode-map
-       "a"        (function mime-viewer/follow-content))
-      (define-key mime/viewer-mode-map
-       "q"        (function mime-viewer/quit))
-      (define-key mime/viewer-mode-map
-       "h"        (function mime-viewer/show-summary))
-      (define-key mime/viewer-mode-map
-       "\C-c\C-x" (function mime-viewer/kill-buffer))
-      (define-key mime/viewer-mode-map
-        "<"        (function beginning-of-buffer))
-      (define-key mime/viewer-mode-map
-        ">"        (function end-of-buffer))
-      (if mouse-button-2
-         (define-key mime/viewer-mode-map
-           mouse-button-2 (function tm:button-dispatcher))
-       )
-      (cond (running-xemacs
-            (defvar mime-viewer/xemacs-popup-menu
-              (cons mime-viewer/menu-title
-                    (mapcar (function
-                             (lambda (item)
-                               (vector (nth 1 item)(nth 2 item) t)
-                               ))
-                            mime-viewer/menu-list)))
-            (defun mime-viewer/xemacs-popup-menu (event)
-              "Popup the menu in the MIME Viewer buffer"
-              (interactive "e")
-              (select-window (event-window event))
-              (set-buffer (event-buffer event))
-              (popup-menu 'mime-viewer/xemacs-popup-menu))
-            (define-key mime/viewer-mode-map
-              mouse-button-3 (function mime-viewer/xemacs-popup-menu))
-            )
-           ((>= emacs-major-version 19)
-            (define-key mime/viewer-mode-map [menu-bar mime-view]
-              (cons mime-viewer/menu-title
-                    (make-sparse-keymap mime-viewer/menu-title)))
-            (mapcar (function
-                     (lambda (item)
-                       (define-key mime/viewer-mode-map
-                         (vector 'menu-bar 'mime-view (car item))
-                         (cons (nth 1 item)(nth 2 item))
-                         )
-                       ))
-                    (reverse mime-viewer/menu-list)
-                    )
-            ))
+      (defvar mime-viewer/xemacs-popup-menu
+       (cons mime-viewer/menu-title
+             (mapcar (function
+                      (lambda (item)
+                        (vector (nth 1 item)(nth 2 item) t)
+                        ))
+                     mime-viewer/menu-list)))
+      (defun mime-viewer/xemacs-popup-menu (event)
+       "Popup the menu in the MIME Viewer buffer"
+       (interactive "e")
+       (select-window (event-window event))
+       (set-buffer (event-buffer event))
+       (popup-menu 'mime-viewer/xemacs-popup-menu))
       ))
 
-(defun mime/viewer-mode (&optional mother ctl encoding ibuf obuf)
+(defun mime-viewer/define-keymap (&optional mother)
+  (let ((mime/viewer-mode-map (if mother
+                                 (copy-keymap mother)
+                               (make-keymap))))
+    (suppress-keymap mime/viewer-mode-map)
+    (define-key mime/viewer-mode-map
+      "u"        (function mime-viewer/up-content))
+    (define-key mime/viewer-mode-map
+      "p"        (function mime-viewer/previous-content))
+    (define-key mime/viewer-mode-map
+      "n"        (function mime-viewer/next-content))
+    (define-key mime/viewer-mode-map
+      " "        (function mime-viewer/scroll-up-content))
+    (define-key mime/viewer-mode-map
+      "\M- "     (function mime-viewer/scroll-down-content))
+    (define-key mime/viewer-mode-map
+      "\177"     (function mime-viewer/scroll-down-content))
+    (define-key mime/viewer-mode-map
+      "\C-m"     (function mime-viewer/next-line-content))
+    (define-key mime/viewer-mode-map
+      "\C-\M-m"  (function mime-viewer/previous-line-content))
+    (define-key mime/viewer-mode-map
+      "v"        (function mime-viewer/play-content))
+    (define-key mime/viewer-mode-map
+      "e"         (function mime-viewer/extract-content))
+    (define-key mime/viewer-mode-map
+      "\C-c\C-p" (function mime-viewer/print-content))
+    (define-key mime/viewer-mode-map
+      "x"        (function mime-viewer/display-x-face))
+    (define-key mime/viewer-mode-map
+      "a"        (function mime-viewer/follow-content))
+    (define-key mime/viewer-mode-map
+      "q"        (function mime-viewer/quit))
+    (define-key mime/viewer-mode-map
+      "h"        (function mime-viewer/show-summary))
+    (define-key mime/viewer-mode-map
+      "\C-c\C-x" (function mime-viewer/kill-buffer))
+    (define-key mime/viewer-mode-map
+      "<"        (function beginning-of-buffer))
+    (define-key mime/viewer-mode-map
+      ">"        (function end-of-buffer))
+    (define-key mime/viewer-mode-map
+      "?"        (function describe-mode))
+    (if mouse-button-2
+       (define-key mime/viewer-mode-map
+         mouse-button-2 (function tm:button-dispatcher))
+      )
+    (cond (running-xemacs
+          (define-key mime/viewer-mode-map
+            mouse-button-3 (function mime-viewer/xemacs-popup-menu))
+          )
+         ((>= emacs-major-version 19)
+          (define-key mime/viewer-mode-map [menu-bar mime-view]
+            (cons mime-viewer/menu-title
+                  (make-sparse-keymap mime-viewer/menu-title)))
+          (mapcar (function
+                   (lambda (item)
+                     (define-key mime/viewer-mode-map
+                       (vector 'menu-bar 'mime-view (car item))
+                       (cons (nth 1 item)(nth 2 item))
+                       )
+                     ))
+                  (reverse mime-viewer/menu-list)
+                  )
+          ))
+    (use-local-map mime/viewer-mode-map)
+    (run-hooks 'mime-viewer/define-keymap-hook)
+    ))
+
+(defun mime/viewer-mode (&optional mother ctl encoding ibuf obuf
+                                  mother-keymap)
   "Major mode for viewing MIME message.
 
 Here is a list of the standard keys for mime/viewer-mode.
@@ -769,16 +781,11 @@ M-RET             Move to previous line
 v              Decode current content as `play mode'
 e              Decode current content as `extract mode'
 C-c C-p                Decode current content as `print mode'
-f              Display X-Face
+a              Followup to current content.
+x              Display X-Face
 q              Quit
 button-2       Move to point under the mouse cursor
                and decode current content as `play mode'
-
-
-Here are all the commands with their current binding,
-listed in key order:
-
-\\{mime/viewer-mode-map}
 "
   (interactive)
   (let ((buf (get-buffer mime/output-buffer-name)))
@@ -797,7 +804,7 @@ listed in key order:
          (progn
            (setq mime::preview/mother-buffer mother)
            ))
-      (use-local-map mime/viewer-mode-map)
+      (mime-viewer/define-keymap mother-keymap)
       (setq mime::preview/content-list (nth 1 ret))
       (goto-char
        (let ((ce (mime::preview-content-info/point-max
@@ -925,7 +932,7 @@ listed in key order:
                                  (mime::content-info/point-min ci)
                                  (mime::content-info/point-max ci)
                                  )
-                                (rfc822/get-header-string-except
+                                (std11-header-string-except
                                  (concat "^"
                                          (apply (function regexp-or) fields)
                                          ":") ""))))
@@ -936,7 +943,7 @@ listed in key order:
                             (insert str)
                           )
                         rcnum))
-               (setq fields (rfc822/get-field-names)
+               (setq fields (std11-collect-field-names)
                      rcnum (cdr rcnum))
                )
              )