2 ;;; A MIME viewer for GNU Emacs
4 ;;; by Morioka Tomohiko, 1994/07/13
23 (defconst mime-viewer/RCS-ID
24 "$Id: tm-view.el,v 6.16 1995/04/19 04:43:09 morioka Exp $")
26 (defconst mime-viewer/version (get-version-string mime-viewer/RCS-ID))
27 (defconst mime/viewer-version mime-viewer/version)
33 (defconst mime/tspecials "\000-\040()<>@,;:\\\"/[\093?.=")
34 (defconst mime/token-regexp
35 (concat "[^" mime/tspecials "]*"))
36 (defconst mime/content-type-subtype-regexp
37 (concat mime/token-regexp "/" mime/token-regexp))
38 (defconst mime/content-parameter-value-regexp
40 message/quoted-string-regexp
43 (defconst mime/output-buffer-name "*MIME-out*")
44 (defconst mime/decoding-buffer-name "*MIME-decoding*")
50 (defvar mime/content-decoding-condition
51 ;;(setq mime/content-decoding-condition
52 '(((type . "text/plain")
53 (method "tm-plain" nil 'file 'type 'encoding 'mode 'name))
54 ;;((type . "text/x-latex")
55 ;; (method "tm-latex" nil 'file 'type 'encoding 'mode 'name))
56 ((type . "audio/basic")
57 (method "tm-au" nil 'file 'type 'encoding 'mode 'name))
59 (method "tm-image" nil 'file 'type 'encoding 'mode 'name))
60 ((type . "image/jpeg")
61 (method "tm-image" nil 'file 'type 'encoding 'mode 'name))
62 ((type . "image/tiff")
63 (method "tm-image" nil 'file 'type 'encoding 'mode 'name))
64 ((type . "image/x-tiff")
65 (method "tm-image" nil 'file 'type 'encoding 'mode 'name))
66 ((type . "image/x-xbm")
67 (method "tm-image" nil 'file 'type 'encoding 'mode 'name))
68 ((type . "image/x-pic")
69 (method "tm-image" nil 'file 'type 'encoding 'mode 'name))
70 ((type . "video/mpeg")
71 (method "tm-mpeg" nil 'file 'type 'encoding 'mode 'name))
72 ((type . "application/octet-stream")
73 (method "tm-file" nil 'file 'type 'encoding 'mode 'name))
74 ;;((type . "message/external-body")
75 ;; (method "xterm" nil
76 ;; "-e" "showexternal"
77 ;; 'file '"access-type" '"name" '"site" '"directory"))
78 ((type . "message/partial")
79 (method . mime/decode-message/partial-region))
81 "-m" "tm" "-x" "-d" "-z" "-e" 'file)(mode . "play"))
84 (defvar mime-viewer/content-filter-alist
85 '(("text/plain" . mime-viewer/filter-text/plain)))
87 (defvar mime-viewer/content-subject-function
89 (lambda (cnum subj ctype params)
91 (format "[%s %s (%s)]\n"
95 (format "%s" (+ num 1))
102 (defvar mime-viewer/content-header-filter-function
103 (function mime-viewer/default-content-header-filter-function))
105 (defvar mime-viewer/childrens-header-showing-Content-Type-list
108 (defvar mime-viewer/ignored-field-list
111 (defun mime-viewer/default-content-header-filter-function (cnum cinfo)
112 (if (and (listp cnum)
114 (mime::content-info/type
115 (mime::article/get-content-region (butlast cnum) cinfo)
117 mime-viewer/childrens-header-showing-Content-Type-list)
119 (delete-region (goto-char (point-min))
120 (or (and (re-search-forward "^$" nil t)
126 (narrow-to-region (goto-char (point-min))
127 (or (and (re-search-forward "^$" nil t)
133 (goto-char (point-min))
134 (while (and (re-search-forward
135 (concat "^" (regexp-quote field) ":")
142 (concat message/field-body-regexp "\n")
148 )) mime-viewer/ignored-field-list)
151 (defvar mime-viewer/default-showing-Content-Type-list
152 '("text/plain" "text/richtext" "text/enriched"
153 "text/x-latex" "application/x-latex"
154 "application/octet-stream" nil))
156 (defvar mime-viewer/decoding-mode "play" "MIME body decoding mode")
162 (defun mime::viewer/quitting-method-for-gnus4 ()
163 (mime-viewer/kill-buffer)
164 (delete-other-windows)
165 (gnus-article-show-summary)
168 (defun mime::viewer/quitting-method-for-rmail ()
169 (mime-viewer/kill-buffer)
171 (delete-other-windows)
174 (defun mime::viewer/quitting-method-for-mh-e ()
175 (let ((win (get-buffer-window
176 mime/output-buffer-name))
178 (mime::preview-content-info/buffer
179 (car mime::preview/content-list)))
184 (mime-viewer/kill-buffer)
186 (let ((name (buffer-name buf)))
187 (string-match "show-" name)
188 (substring name (match-end 0))
190 ;; patch for mh-narrow.el
191 ;; by YAMAOKA Katsumi <yamaoka@ga.sony.co.jp>
192 (if (and (featurep 'mh-narrow)
193 (fboundp 'mh-narrow-to-page))
195 (set-buffer mh-show-buffer)
196 (mh-narrow-to-page)))
200 (defvar mime-viewer/quitting-method-alist
201 '((gnus-article-mode . mime::viewer/quitting-method-for-gnus4)
202 (rmail-mode . mime::viewer/quitting-method-for-rmail)
203 (mh-show-mode . mime::viewer/quitting-method-for-mh-e)
204 (mime/show-message-mode
206 (set-window-configuration
207 mime/show-mode-old-window-configuration)
208 (let ((mother mime/mother-buffer))
210 (mime::preview-content-info/buffer
211 (car mime::preview/content-list)))
212 (mime-viewer/kill-buffer)
213 (pop-to-buffer mother)
214 (goto-char (point-min))
215 (mime-viewer/up-content)
226 (defun mime::make-content-info (beg end ctype params encoding children)
227 (vector beg end ctype params encoding children)
230 (defun mime::content-info/point-min (cinfo)
234 (defun mime::content-info/point-max (cinfo)
238 (defun mime::content-info/type (cinfo)
242 (defun mime::content-info/parameters (cinfo)
246 (defun mime::content-info/encoding (cinfo)
250 (defun mime::content-info/children (cinfo)
254 ;;; @@ preview-content-info
257 (defun mime::make-preview-content-info (beg end buf cinfo)
258 (vector beg end buf cinfo)
261 (defun mime::preview-content-info/point-min (pcinfo)
265 (defun mime::preview-content-info/point-max (pcinfo)
269 (defun mime::preview-content-info/buffer (pcinfo)
273 (defun mime::preview-content-info/content-info (pcinfo)
278 ;;; @ buffer local variables
281 (defvar mime::article/content-info)
282 (defvar mime::article/preview-buffer)
284 (defvar mime::preview/content-list nil)
285 (defvar mime::preview/original-major-mode nil)
291 (defun mime-viewer/parse-message (&optional ctl encoding)
292 (make-variable-buffer-local 'mime::article/content-info)
293 (setq mime::article/content-info (mime-viewer/parse ctl encoding))
294 (let ((ret (mime-viewer/make-preview-buffer)))
295 (make-variable-buffer-local 'mime::article/preview-buffer)
296 (setq mime::article/preview-buffer (car ret))
299 (defun mime-viewer/parse (&optional ctl encoding)
304 (goto-char (point-min))
309 (setq encoding (progn
310 (goto-char (point-min))
311 (mime/Content-Transfer-Encoding)
314 (let ((ctype (car ctl))
318 (setq ctype (downcase ctype))
320 (if (stringp encoding)
321 (setq encoding (downcase encoding))
323 (let ((boundary (assoc "boundary" params)))
324 (search-forward "\n\n" nil t)
327 (message/strip-quoted-string (cdr boundary)))
328 (mime-viewer/parse-multipart
331 (search-forward (concat "--" boundary "--\n") nil t)
334 boundary ctype params encoding)
336 ((string= ctype "message/rfc822")
337 (mime::make-content-info
338 (point-min) (point-max)
339 ctype params encoding
342 (narrow-to-region (match-end 0) (point-max))
343 (list (mime-viewer/parse))
348 (mime::make-content-info (point-min) (point-max)
349 ctype params encoding nil)
353 (defun mime-viewer/parse-multipart (beg end boundary ctype params encoding)
354 (let ((sep (concat "^--" boundary "$"))
355 cb ce ct ret ncb children)
358 (narrow-to-region beg end)
359 (goto-char (point-min))
360 (search-forward (concat "--" boundary "\n") nil t)
361 (setq cb (match-end 0))
362 (while (re-search-forward sep nil t)
363 (setq ce (match-beginning 0))
364 (setq ncb (match-end 0))
367 (narrow-to-region cb ce)
368 (setq ret (mime-viewer/parse))
370 (setq children (nconc children (list ret)))
371 (goto-char (mime::content-info/point-max ret))
372 (search-forward (concat "--" boundary "\n") nil t)
373 (goto-char (setq cb (match-end 0)))
375 (setq ce (point-max))
378 (narrow-to-region cb ce)
379 (setq ret (mime-viewer/parse))
381 (setq children (nconc children (list ret)))
383 (setq beg (point-min))
385 (mime::make-content-info beg end ctype params encoding children)
388 (defun mime::parse-parameter (str)
389 (let ((ret (message::parse "\;" str)))
392 (message::parse mime/token-regexp
393 (message::parsed/rest ret)))
394 (let ((parameter (downcase (message::parsed/matched ret))))
395 (if (setq ret (message::parse "=" (message::parsed/rest ret)))
398 mime/content-parameter-value-regexp
399 (message::parsed/rest ret)))
400 (message::make-parsed
402 (message/strip-quoted-string
403 (message::parsed/matched ret))
405 (message::parsed/rest ret)
409 (defun mime::parse-field-body/Content-Type (str)
410 (let ((ret (message::parse mime/content-type-subtype-regexp str)))
412 (let ((ctype (downcase (message::parsed/matched ret)))
415 (setq str (message::parsed/rest ret))
416 (setq ret (mime::parse-parameter str))
418 (setq dest (cons (message::parsed/matched ret) dest))
420 (if (string-match "^[ \t]*$" str)
421 (cons ctype (reverse dest))
424 (defun mime/Content-Type ()
425 (let ((str (message/get-field-body "Content-Type")))
427 (mime::parse-field-body/Content-Type
428 (message/unfolding-string str))
431 (defun mime/Content-Transfer-Encoding (&optional default-encoding)
434 (if (and (re-search-forward "^Content-Transfer-Encoding:[ \t]*" nil t)
435 (re-search-forward mime/token-regexp nil t)
437 (downcase (buffer-substring (match-beginning 0) (match-end 0)))
441 (defun mime/get-subject (param)
445 (or (and (setq ret (assoc "name" param))
446 (message/strip-quoted-string (cdr ret))
448 (and (setq ret (assoc "x-name" param))
449 (message/strip-quoted-string (cdr ret))
452 (narrow-to-region (point-min)
453 (or (and (search-forward "\n\n" nil t)
458 (message/get-field-body "Content-Description")
459 (message/get-field-body "Subject")
464 (defun mime/get-name (param)
465 (replace-as-filename (mime/get-subject param))
468 (defun mime-viewer/make-preview-buffer (&optional buf cinfo obuf)
469 (let ((the-buf (current-buffer)) pcl dest)
477 (switch-to-buffer buf)
478 (setq cinfo mime::article/content-info)
481 (setq obuf (concat "*Preview-" (buffer-name buf) "*"))
483 (setq pcl (mime::make-flat-content-list cinfo))
484 (if (get-buffer obuf)
491 (let ((beg (mime::content-info/point-min cell))
492 (end (mime::content-info/point-max cell))
493 (ctype (mime::content-info/type cell))
494 (params (mime::content-info/parameters cell))
495 cnum e nb ne subj str)
496 (setq cnum (mime::get-point-content-number beg cinfo))
497 (switch-to-buffer buf)
502 mime-viewer/default-showing-Content-Type-list))
506 (search-forward "\n\n" nil t)
510 (if (> e (point-max))
513 (setq str (buffer-substring beg e))
514 (switch-to-buffer obuf)
521 (narrow-to-region nb ne)
522 (mime/decode-message-header)
523 (setq subj (mime/get-subject params))
527 mime-viewer/content-filter-alist))))
528 (if (and f (fboundp f))
529 (funcall f ctype params)
531 (funcall mime-viewer/content-header-filter-function
534 (funcall mime-viewer/content-subject-function
535 cnum subj ctype params)
536 (setq ne (point-max))
537 (mime::make-preview-content-info nb (- ne 1)
543 (set-buffer-modified-p nil)
544 (setq buffer-read-only t)
545 (switch-to-buffer the-buf)
550 ;;; @ content information
553 (defun mime::get-point-content-number (p &optional cinfo)
555 (setq cinfo mime::article/content-info)
557 (let ((b (mime::content-info/point-min cinfo))
558 (e (mime::content-info/point-max cinfo))
559 (c (mime::content-info/children cinfo))
561 (if (and (<= b p)(<= p e))
562 (or (let (co ret (sn 0))
566 (setq ret (mime::get-point-content-number p co))
567 (cond ((eq ret t) (throw 'tag (list sn)))
568 (ret (throw 'tag (cons sn ret)))
575 (defun mime::article/get-content-region (cn &optional cinfo)
577 (setq cinfo mime::article/content-info)
584 (let ((rc (nth sn (mime::content-info/children cinfo))))
586 (mime::article/get-content-region (cdr cn) rc)
590 (defun mime::make-flat-content-list (&optional cinfo)
592 (setq cinfo mime::article/content-info)
594 (let ((dest (list cinfo))
595 (rcl (mime::content-info/children cinfo))
598 (setq dest (nconc dest (mime::make-flat-content-list (car rcl))))
603 (defun mime::point-preview-content (p &optional pcl)
605 (setq pcl mime::preview/content-list)
611 (if (and (<= (mime::preview-content-info/point-min cell) p)
612 (<= p (mime::preview-content-info/point-max cell))
625 (defun mime/Quoted-Printable-decode-region (beg end)
629 (narrow-to-region beg end)
630 (goto-char (point-min))
631 (while (re-search-forward "=\n" nil t)
634 (goto-char (point-min))
636 (while (re-search-forward mime/Quoted-Printable-octet-regexp nil t)
637 (setq b (match-beginning 0))
638 (setq e (match-end 0))
639 (setq str (buffer-substring b e))
641 (insert (mime/Quoted-Printable-decode-string str))
645 (defun mime/Base64-decode-region (beg end)
649 (narrow-to-region beg end)
650 (goto-char (point-min))
651 (while (search-forward "\n" nil t)
654 (let ((str (buffer-substring (point-min)(point-max))))
655 (delete-region (point-min)(point-max))
656 (insert (mime/base64-decode-string str))
659 (defun mime/make-method-args (cal format)
664 (let ((ret (cdr (assoc (eval arg) cal))))
672 (defun mime/start-external-method-region (beg end cal)
675 (narrow-to-region beg end)
677 (let ((method (cdr (assoc 'method cal)))
678 (name (mime/get-name cal))
681 (let ((file (make-temp-name
682 (expand-file-name "TM" mime/tmp-dir)))
686 (search-forward "\n\n" nil t)
687 (setq b (match-end 0))
690 (write-region b end file)
692 'name (replace-as-filename name) cal))
693 (setq cal (put-alist 'file file cal))
696 mime/output-buffer-name (car method)
698 (mime/make-method-args cal (cdr (cdr method)))
700 (apply (function start-process) args)
701 (mime/show-output-buffer)
705 (defun mime/decode-message/partial-region (beg end cal)
707 (let* ((root-dir (expand-file-name
708 (concat "m-prts-" (user-login-name)) mime/tmp-dir))
709 (id (cdr (assoc "id" cal)))
710 (number (cdr (assoc "number" cal)))
711 (total (cdr (assoc "total" cal)))
712 (the-buf (current-buffer))
714 (mother mime::article/preview-buffer))
715 (if (not (file-exists-p root-dir))
716 (make-directory root-dir)
718 (setq id (replace-as-filename id))
719 (setq root-dir (concat root-dir "/" id))
720 (if (not (file-exists-p root-dir))
721 (make-directory root-dir)
723 (setq file (concat root-dir "/FULL"))
724 (if (not (file-exists-p file))
726 (re-search-forward "^$")
727 (goto-char (+ (match-end 0) 1))
728 (setq file (concat root-dir "/" number))
729 (write-region (point) (point-max) file)
730 (if (get-buffer "*MIME-temp*")
731 (kill-buffer "*MIME-temp*")
733 (switch-to-buffer "*MIME-temp*")
735 (max (string-to-int total))
739 (setq file (concat root-dir "/" (int-to-string i)))
740 (if (not (file-exists-p file))
742 (switch-to-buffer the-buf)
745 (insert-file-contents file)
746 (goto-char (point-max))
749 (delete-other-windows)
750 (write-file (concat root-dir "/FULL"))
751 (setq major-mode 'mime/show-message-mode)
752 (mime/viewer-mode mother)
753 (pop-to-buffer (current-buffer))
757 (delete-other-windows)
759 (setq major-mode 'mime/show-message-mode)
760 (mime/viewer-mode mother)
761 (pop-to-buffer (current-buffer))
765 (defun mime/get-content-decoding-alist (al)
766 (get-unified-alist mime/content-decoding-condition al)
769 (defun mime::article/decode-content-region (cinfo)
771 (let ((beg (mime::content-info/point-min cinfo))
772 (end (mime::content-info/point-max cinfo))
773 (ctype (mime::content-info/type cinfo))
774 (params (mime::content-info/parameters cinfo))
775 (encoding (mime::content-info/encoding cinfo))
778 (let (method cal ret)
779 (setq cal (append (list (cons 'type ctype)
780 (cons 'encoding encoding)
781 (cons 'major-mode major-mode)
784 (if mime-viewer/decoding-mode
786 (cons 'mode mime-viewer/decoding-mode)
789 (setq ret (mime/get-content-decoding-alist cal))
790 (setq method (cdr (assoc 'method ret)))
791 (cond ((and (symbolp method)
793 (funcall method beg end ret)
795 ((and (listp method)(stringp (car method)))
796 (mime/start-external-method-region beg end ret)
798 (t (mime/show-output-buffer
799 "No method are specified for %s\n" ctype)
804 (defun mime/show-output-buffer (&rest forms)
805 (let ((the-buf (current-buffer)))
806 (if (null (get-buffer-window mime/output-buffer-name))
807 (split-window-vertically (/ (* (window-height) 3) 4))
809 (pop-to-buffer mime/output-buffer-name)
810 (goto-char (point-max))
812 (insert (apply (function format) forms))
814 (pop-to-buffer the-buf)
821 (defun mime-viewer/filter-text/plain (ctype params)
824 (let ((charset (cdr (assoc "charset" params)))
828 (goto-char (point-min))
829 (narrow-to-region (point-min)
830 (or (and (search-forward "\n\n" nil t)
833 (goto-char (point-min))
834 (mime/Content-Transfer-Encoding "7bit")
836 (beg (point-min)) (end (point-max))
838 (goto-char (point-min))
839 (if (search-forward "\n\n" nil t)
840 (setq beg (match-end 0))
842 (if (cond ((string= encoding "quoted-printable")
843 (mime/Quoted-Printable-decode-region beg end)
845 ((string= encoding "base64")
846 (mime/Base64-decode-region beg end)
848 (mime/code-convert-region-to-emacs beg (point-max) charset)
853 ;;; @ MIME viewer mode
856 (defvar mime/viewer-mode-map nil)
857 (if (null mime/viewer-mode-map)
859 (setq mime/viewer-mode-map (make-keymap))
860 (suppress-keymap mime/viewer-mode-map)
861 (define-key mime/viewer-mode-map
862 "u" (function mime-viewer/up-content))
863 (define-key mime/viewer-mode-map
864 "p" (function mime-viewer/previous-content))
865 (define-key mime/viewer-mode-map
866 "n" (function mime-viewer/next-content))
867 (define-key mime/viewer-mode-map
868 " " (function mime-viewer/scroll-up-content))
869 (define-key mime/viewer-mode-map
870 "\M- " (function mime-viewer/scroll-down-content))
871 (define-key mime/viewer-mode-map
872 "\177" (function mime-viewer/scroll-down-content))
873 (define-key mime/viewer-mode-map
874 "\C-m" (function mime-viewer/next-line-content))
875 (define-key mime/viewer-mode-map
876 "\C-\M-m" (function mime-viewer/previous-line-content))
877 (define-key mime/viewer-mode-map
878 "v" (function mime-viewer/play-content))
879 (define-key mime/viewer-mode-map
880 "e" (function mime-viewer/extract-content))
881 (define-key mime/viewer-mode-map
882 "\C-c\C-p" (function mime-viewer/print-content))
883 (define-key mime/viewer-mode-map
884 "q" (function mime-viewer/quit))
885 (define-key mime/viewer-mode-map
886 "\C-c\C-x" (function mime-viewer/kill-buffer))
889 (defun mime/viewer-mode (&optional mother ctl encoding)
890 "Major mode for viewing MIME message.
892 u Move to upper content
893 p Move to previous content
894 n Move to next content
898 RET Move to next line
899 M-RET Move to previous line
900 v Decode the content as `play mode'
901 e Decode the content as `extract mode'
902 C-c C-p Decode the content as `print mode'
906 (let ((buf (get-buffer mime/output-buffer-name))
907 (the-buf (current-buffer))
911 (switch-to-buffer buf)
913 (switch-to-buffer the-buf)
915 (let ((ret (mime-viewer/parse-message ctl encoding))
917 (switch-to-buffer (car ret))
918 (setq major-mode 'mime/viewer-mode)
919 (setq mode-name "MIME-View")
920 (make-variable-buffer-local 'mime::preview/original-major-mode)
921 (setq mime::preview/original-major-mode
924 (make-variable-buffer-local
925 'mime/show-mode-old-window-configuration)
926 (setq mime/show-mode-old-window-configuration
927 (current-window-configuration))
928 (make-variable-buffer-local 'mime/mother-buffer)
929 (setq mime/mother-buffer mother)
930 'mime/show-message-mode)
932 (use-local-map mime/viewer-mode-map)
933 (make-variable-buffer-local 'mime::preview/content-list)
934 (setq mime::preview/content-list (nth 1 ret))
936 (let ((ce (mime::preview-content-info/point-max
937 (car mime::preview/content-list)
940 (goto-char (point-min))
941 (search-forward "\n\n" nil t)
942 (setq e (match-end 0))
946 (run-hooks 'mime/viewer-mode-hook)
949 (defun mime::preview/decode-content ()
951 (let ((pc (mime::point-preview-content (point))))
953 (let ((the-buf (current-buffer)))
954 (switch-to-buffer (mime::preview-content-info/buffer pc))
955 (mime::article/decode-content-region
956 (mime::preview-content-info/content-info pc))
957 (if (eq (current-buffer)
958 (mime::preview-content-info/buffer pc))
959 (switch-to-buffer the-buf)
963 (defun mime-viewer/play-content ()
965 (let ((mime-viewer/decoding-mode "play"))
966 (mime::preview/decode-content)
969 (defun mime-viewer/extract-content ()
971 (let ((mime-viewer/decoding-mode "extract"))
972 (mime::preview/decode-content)
975 (defun mime-viewer/print-content ()
977 (let ((mime-viewer/decoding-mode "print"))
978 (mime::preview/decode-content)
981 (defun mime-viewer/up-content ()
983 (let ((pc (mime::point-preview-content (point))) cinfo
984 (the-buf (current-buffer))
986 (switch-to-buffer (mime::preview-content-info/buffer pc))
987 (setq cinfo (mime::preview-content-info/content-info pc))
988 (setq cn (mime::get-point-content-number
989 (mime::content-info/point-min cinfo)))
991 (mime-viewer/quit the-buf
992 (mime::preview-content-info/buffer pc)
994 (setq r (mime::article/get-content-region (butlast cn)))
995 (switch-to-buffer the-buf)
997 (let ((rpcl mime::preview/content-list) cell)
999 (setq cell (car rpcl))
1000 (if (eq r (mime::preview-content-info/content-info cell))
1002 (goto-char (mime::preview-content-info/point-min cell))
1005 (setq rpcl (cdr rpcl))
1009 (defun mime-viewer/previous-content ()
1011 (let* ((pcl mime::preview/content-list)
1013 (i (- (length pcl) 1))
1017 (setq beg (mime::preview-content-info/point-min (nth i pcl)))
1019 (throw 'tag (goto-char beg))
1025 (defun mime-viewer/next-content ()
1027 (let ((pcl mime::preview/content-list)
1032 (setq beg (mime::preview-content-info/point-min (car pcl)))
1034 (throw 'tag (goto-char beg))
1036 (setq pcl (cdr pcl))
1040 (defun mime-viewer/scroll-up-content (&optional h)
1043 (setq h (- (window-height) 1))
1045 (let ((pcl mime::preview/content-list)
1051 (setq beg (mime::preview-content-info/point-min (car pcl)))
1055 (setq pcl (cdr pcl))
1063 (defun mime-viewer/scroll-down-content (&optional h)
1066 (setq h (- (window-height) 1))
1068 (let ((pcl mime::preview/content-list)
1072 (or (let ((i (- (length pcl) 1)))
1075 (setq beg (mime::preview-content-info/point-min
1083 (forward-line (- h))
1088 (defun mime-viewer/next-line-content ()
1090 (mime-viewer/scroll-up-content 1)
1093 (defun mime-viewer/previous-line-content ()
1095 (mime-viewer/scroll-down-content 1)
1098 (defun mime-viewer/quit (&optional the-buf buf)
1101 (setq the-buf (current-buffer))
1104 (setq buf (mime::preview-content-info/buffer
1105 (mime::point-preview-content (point))))
1108 (switch-to-buffer buf)
1109 (assoc major-mode mime-viewer/quitting-method-alist)
1113 (switch-to-buffer the-buf)
1118 (defun mime-viewer/kill-buffer ()
1120 (kill-buffer (current-buffer))
1123 (fset 'mime/view-mode 'mime/viewer-mode)
1125 (run-hooks 'tm-view-load-hook)