comparison lisp/mail/rmailmm.el @ 112257:103d72f0a1d5

Another improvement of MIME handling in rmail.
author Kenichi Handa <handa@m17n.org>
date Wed, 12 Jan 2011 15:08:55 +0900
parents 6fd3dcdcc675
children 932e0e85675a
comparison
equal deleted inserted replaced
112240:6fd3dcdcc675 112257:103d72f0a1d5
271 271
272 (defun rmail-mime-entity-segment (pos &optional entity) 272 (defun rmail-mime-entity-segment (pos &optional entity)
273 "Return a vector describing the displayed region of a MIME-entity at POS. 273 "Return a vector describing the displayed region of a MIME-entity at POS.
274 Optional 2nd argument ENTITY is the MIME-entity at POS. 274 Optional 2nd argument ENTITY is the MIME-entity at POS.
275 The value is a vector [ INDEX HEADER TAGLINE BODY END], where 275 The value is a vector [ INDEX HEADER TAGLINE BODY END], where
276 INDEX: index into the returned vector indicating where POS is (1..3).
276 HEADER: the position of the beginning of a header 277 HEADER: the position of the beginning of a header
277 TAGLINE: the position of the beginning of a tagline 278 TAGLINE: the position of the beginning of a tagline
278 BODY: the position of the beginning of a body 279 BODY: the position of the beginning of a body
279 END: the position of the end of the entity. 280 END: the position of the end of the entity."
280 INDEX: index into the returned vector indicating where POS is."
281 (save-excursion 281 (save-excursion
282 (or entity 282 (or entity
283 (setq entity (get-text-property pos 'rmail-mime-entity))) 283 (setq entity (get-text-property pos 'rmail-mime-entity)))
284 (if (not entity) 284 (if (not entity)
285 (vector 1 (point) (point) (point) (point)) 285 (vector 1 (point) (point) (point) (point))
316 (setq end (next-single-property-change end 'rmail-mime-entity 316 (setq end (next-single-property-change end 'rmail-mime-entity
317 nil (point-max))))) 317 nil (point-max)))))
318 (setq end body-beg)) 318 (setq end body-beg))
319 (vector index beg tagline-beg body-beg end))))) 319 (vector index beg tagline-beg body-beg end)))))
320 320
321 (defun rmail-mime-next-item ()
322 "Move point to the next displayed item of the current MIME entity.
323 A MIME entity has three items; header, tagline, and body.
324 If we are in the last item of the entity, move point to the first
325 item of the next entity. If we reach the end of buffer, move
326 point to the first item of the first entity (i.e. the beginning
327 of buffer)."
328 (interactive)
329 (if (rmail-mime-message-p)
330 (let* ((segment (rmail-mime-entity-segment (point)))
331 (next-pos (aref segment (1+ (aref segment 0))))
332 (button (next-button (point))))
333 (goto-char (if (and button (< (button-start button) next-pos))
334 (button-start button)
335 next-pos))
336 (if (eobp)
337 (goto-char (point-min))))))
338
339 (defun rmail-mime-previous-item ()
340 "Move point to the previous displayed item of the current MIME message.
341 A MIME entity has three items; header, tagline, and body.
342 If we are at the beginning of the first item of the entity, move
343 point to the last item of the previous entity. If we reach the
344 beginning of buffer, move point to the last item of the last
345 entity."
346 (interactive)
347 (when (rmail-mime-message-p)
348 (if (bobp)
349 (goto-char (point-max)))
350 (let* ((segment (rmail-mime-entity-segment (1- (point))))
351 (prev-pos (aref segment (aref segment 0)))
352 (button (previous-button (point))))
353 (goto-char (if (and button (> (button-start button) prev-pos))
354 (button-start button)
355 prev-pos)))))
356
357 (defun rmail-mime-shown-mode (entity) 321 (defun rmail-mime-shown-mode (entity)
358 "Make MIME-entity ENTITY displayed by the default way." 322 "Make MIME-entity ENTITY displayed by the default way."
359 (let ((new (aref (rmail-mime-entity-display entity) 1))) 323 (let ((new (aref (rmail-mime-entity-display entity) 1)))
360 (aset new 0 (aref (rmail-mime-entity-header entity) 2)) 324 (aset new 0 (aref (rmail-mime-entity-header entity) 2))
361 (aset new 1 (aref (rmail-mime-entity-tagline entity) 2)) 325 (aset new 1 (aref (rmail-mime-entity-tagline entity) 2))
362 (aset new 2 (aref (rmail-mime-entity-body entity) 2)))) 326 (aset new 2 (aref (rmail-mime-entity-body entity) 2)))
327 (dolist (child (rmail-mime-entity-children entity))
328 (rmail-mime-shown-mode child)))
363 329
364 (defun rmail-mime-hidden-mode (entity top) 330 (defun rmail-mime-hidden-mode (entity)
365 "Make MIME-entity ENTITY displayed in the hidden mode. 331 "Make MIME-entity ENTITY displayed in the hidden mode."
366 If TOP is non-nil, display ENTITY only by the tagline. 332 (let ((new (aref (rmail-mime-entity-display entity) 1)))
367 Otherwise, don't display ENTITY." 333 (aset new 0 nil)
368 (if top 334 (aset new 1 t)
369 (let ((new (aref (rmail-mime-entity-display entity) 1))) 335 (aset new 2 nil))
370 (aset new 0 nil)
371 (aset new 1 top)
372 (aset new 2 nil)
373 (aset (rmail-mime-entity-body entity) 2 nil))
374 (let ((current (aref (rmail-mime-entity-display entity) 0)))
375 (aset current 0 nil)
376 (aset current 1 nil)
377 (aset current 2 nil)))
378 (dolist (child (rmail-mime-entity-children entity)) 336 (dolist (child (rmail-mime-entity-children entity))
379 (rmail-mime-hidden-mode child nil))) 337 (rmail-mime-hidden-mode child)))
380 338
381 (defun rmail-mime-raw-mode (entity) 339 (defun rmail-mime-raw-mode (entity)
382 "Make MIME-entity ENTITY displayed in the raw mode." 340 "Make MIME-entity ENTITY displayed in the raw mode."
383 (let ((new (aref (rmail-mime-entity-display entity) 1))) 341 (let ((new (aref (rmail-mime-entity-display entity) 1)))
384 (aset new 0 'raw) 342 (aset new 0 'raw)
385 (aset new 1 nil) 343 (aset new 1 nil)
386 (aset new 2 'raw) 344 (aset new 2 'raw))
387 (dolist (child (rmail-mime-entity-children entity)) 345 (dolist (child (rmail-mime-entity-children entity))
388 (rmail-mime-hidden-mode child nil)))) 346 (rmail-mime-raw-mode child)))
389 347
390 (defun rmail-mime-toggle-raw (entity) 348 (defun rmail-mime-toggle-raw (entity)
391 "Toggle on and off the raw display mode of MIME-entity ENTITY." 349 "Toggle on and off the raw display mode of MIME-entity ENTITY."
392 (let* ((pos (if (eobp) (1- (point-max)) (point))) 350 (let* ((pos (if (eobp) (1- (point-max)) (point)))
393 (entity (get-text-property pos 'rmail-mime-entity)) 351 (entity (get-text-property pos 'rmail-mime-entity))
404 (goto-char (aref segment 1)) 362 (goto-char (aref segment 1))
405 (rmail-mime-insert entity) 363 (rmail-mime-insert entity)
406 (restore-buffer-modified-p modified))))) 364 (restore-buffer-modified-p modified)))))
407 365
408 (defun rmail-mime-toggle-hidden () 366 (defun rmail-mime-toggle-hidden ()
409 "Toggle on and off the hidden display mode of MIME-entity ENTITY." 367 "Hide or show the body of MIME-entity at point."
410 (interactive) 368 (interactive)
411 (when (rmail-mime-message-p) 369 (when (rmail-mime-message-p)
412 (let* ((rmail-mime-mbox-buffer rmail-view-buffer) 370 (let* ((rmail-mime-mbox-buffer rmail-view-buffer)
413 (rmail-mime-view-buffer (current-buffer)) 371 (rmail-mime-view-buffer (current-buffer))
414 (pos (if (eobp) (1- (point-max)) (point))) 372 (pos (if (eobp) (1- (point-max)) (point)))
417 (segment (rmail-mime-entity-segment pos entity))) 375 (segment (rmail-mime-entity-segment pos entity)))
418 (if (aref current 2) 376 (if (aref current 2)
419 ;; Enter the hidden mode. 377 ;; Enter the hidden mode.
420 (progn 378 (progn
421 ;; If point is in the body part, move it to the tagline 379 ;; If point is in the body part, move it to the tagline
422 ;; (or the header if headline is not displayed). 380 ;; (or the header if tagline is not displayed).
423 (if (= (aref segment 0) 3) 381 (if (= (aref segment 0) 3)
424 (goto-char (aref segment 2))) 382 (goto-char (aref segment 2)))
425 (rmail-mime-hidden-mode entity t) 383 (rmail-mime-hidden-mode entity)
426 ;; If the current entity is the topmost one, display the 384 ;; If the current entity is the topmost one, display the
427 ;; header. 385 ;; header.
428 (if (and rmail-mime-mbox-buffer (= (aref segment 1) (point-min))) 386 (if (and rmail-mime-mbox-buffer (= (aref segment 1) (point-min)))
429 (let ((new (aref (rmail-mime-entity-display entity) 1))) 387 (let ((new (aref (rmail-mime-entity-display entity) 1)))
430 (aset new 0 t)))) 388 (aset new 0 t))))
431 ;; Enter the shown mode. 389 ;; Enter the shown mode.
432 (aset (rmail-mime-entity-body entity) 2 t) 390 (rmail-mime-shown-mode entity)
433 (rmail-mime-shown-mode entity)) 391 ;; Force this body shown.
392 (aset (aref (rmail-mime-entity-display entity) 1) 2 t))
434 (let ((inhibit-read-only t) 393 (let ((inhibit-read-only t)
435 (modified (buffer-modified-p)) 394 (modified (buffer-modified-p))
436 (rmail-mime-mbox-buffer rmail-view-buffer) 395 (rmail-mime-mbox-buffer rmail-view-buffer)
437 (rmail-mime-view-buffer rmail-buffer)) 396 (rmail-mime-view-buffer rmail-buffer))
438 (save-excursion 397 (save-excursion
439 (goto-char (aref segment 1)) 398 (goto-char (aref segment 1))
440 (rmail-mime-insert entity) 399 (rmail-mime-insert entity)
441 (restore-buffer-modified-p modified)))))) 400 (restore-buffer-modified-p modified))))))
442 401
443 (define-key rmail-mode-map "\t" 'rmail-mime-next-item) 402 (define-key rmail-mode-map "\t" 'forward-button)
444 (define-key rmail-mode-map [backtab] 'rmail-mime-previous-item) 403 (define-key rmail-mode-map [backtab] 'backward-button)
445 (define-key rmail-mode-map "\r" 'rmail-mime-toggle-hidden) 404 (define-key rmail-mode-map "\r" 'rmail-mime-toggle-hidden)
446 405
447 ;;; Handlers 406 ;;; Handlers
448 407
449 (defun rmail-mime-insert-tagline (entity &rest item-list) 408 (defun rmail-mime-insert-tagline (entity &rest item-list)
451 ITEM-LIST is a list of strings or button-elements (list) to be added 410 ITEM-LIST is a list of strings or button-elements (list) to be added
452 to the tag line." 411 to the tag line."
453 (insert "[") 412 (insert "[")
454 (let ((tag (aref (rmail-mime-entity-tagline entity) 0))) 413 (let ((tag (aref (rmail-mime-entity-tagline entity) 0)))
455 (if (> (length tag) 0) (insert (substring tag 1) ":"))) 414 (if (> (length tag) 0) (insert (substring tag 1) ":")))
456 (insert (car (rmail-mime-entity-type entity))) 415 (insert (car (rmail-mime-entity-type entity)) " ")
416 (insert-button (let ((new (aref (rmail-mime-entity-display entity) 1)))
417 (if (aref new 2) "Hide" "Show"))
418 :type 'rmail-mime-toggle
419 'help-echo "mouse-2, RET: Toggle show/hide")
457 (dolist (item item-list) 420 (dolist (item item-list)
458 (when item 421 (when item
459 (if (stringp item) 422 (if (stringp item)
460 (insert item) 423 (insert item)
461 (apply 'insert-button item)))) 424 (apply 'insert-button item))))
462 (insert "]\n")) 425 (insert "]\n"))
463 426
427 (defun rmail-mime-update-tagline (entity)
428 "Update the current tag line for MIME-entity ENTITY."
429 (let ((inhibit-read-only t)
430 (modified (buffer-modified-p))
431 ;; If we are going to show the body, the new button label is
432 ;; "Hide". Otherwise, it's "Show".
433 (label (if (aref (aref (rmail-mime-entity-display entity) 1) 2) "Hide"
434 "Show"))
435 (button (next-button (point))))
436 ;; Go to the second character of the button "Show" or "Hide".
437 (goto-char (1+ (button-start button)))
438 (setq button (button-at (point)))
439 (save-excursion
440 (insert label)
441 (delete-region (point) (button-end button)))
442 (delete-region (button-start button) (point))
443 (put-text-property (point) (button-end button) 'rmail-mime-entity entity)
444 (restore-buffer-modified-p modified)
445 (forward-line 1)))
446
464 (defun rmail-mime-insert-header (header) 447 (defun rmail-mime-insert-header (header)
465 "Decode and insert a MIME-entity header HEADER in the current buffer. 448 "Decode and insert a MIME-entity header HEADER in the current buffer.
466 HEADER is a vector [BEG END DEFAULT-STATUS]. 449 HEADER is a vector [BEG END DEFAULT-STATUS].
467 See `rmail-mime-entity' for the detail." 450 See `rmail-mime-entity' for the detail."
468 (let ((pos (point)) 451 (let ((pos (point))
541 (delete-char (- (aref segment 2) (aref segment 1)))) 524 (delete-char (- (aref segment 2) (aref segment 1))))
542 (if (aref new 0) 525 (if (aref new 0)
543 (rmail-mime-insert-header header))) 526 (rmail-mime-insert-header header)))
544 ;; tagline 527 ;; tagline
545 (if (eq (aref current 1) (aref new 1)) 528 (if (eq (aref current 1) (aref new 1))
546 (forward-char (- (aref segment 3) (aref segment 2))) 529 (if (or (not (aref current 1))
530 (eq (aref current 2) (aref new 2)))
531 (forward-char (- (aref segment 3) (aref segment 2)))
532 (rmail-mime-update-tagline entity))
547 (if (aref current 1) 533 (if (aref current 1)
548 (delete-char (- (aref segment 3) (aref segment 2)))) 534 (delete-char (- (aref segment 3) (aref segment 2))))
549 (if (aref new 1) 535 (if (aref new 1)
550 (rmail-mime-insert-tagline entity))) 536 (rmail-mime-insert-tagline entity)))
551 ;; body 537 ;; body
596 (setq data 582 (setq data
597 (buffer-substring-no-properties (point-min) (point-max)))))) 583 (buffer-substring-no-properties (point-min) (point-max))))))
598 (insert-image (create-image data (cdr bulk-data) t)) 584 (insert-image (create-image data (cdr bulk-data) t))
599 (insert "\n"))) 585 (insert "\n")))
600 586
601 (defun rmail-mime-image (button) 587 (defun rmail-mime-toggle-button (button)
602 "Display the image associated with BUTTON." 588 "Hide or show the body of the MIME-entity associated with BUTTON."
603 (save-excursion 589 (save-excursion
604 (goto-char (button-end button)) 590 (goto-char (button-start button))
605 (rmail-mime-toggle-hidden))) 591 (rmail-mime-toggle-hidden)))
606 592
607 (define-button-type 'rmail-mime-image 'action 'rmail-mime-image) 593 (define-button-type 'rmail-mime-toggle 'action 'rmail-mime-toggle-button)
608 594
609 595
610 (defun rmail-mime-bulk-handler (content-type 596 (defun rmail-mime-bulk-handler (content-type
611 content-disposition 597 content-disposition
612 content-transfer-encoding) 598 content-transfer-encoding)
625 directly." 611 directly."
626 (let ((content-type (car (rmail-mime-entity-type entity))) 612 (let ((content-type (car (rmail-mime-entity-type entity)))
627 (size (cdr (assq 'size (cdr (rmail-mime-entity-disposition entity))))) 613 (size (cdr (assq 'size (cdr (rmail-mime-entity-disposition entity)))))
628 (bulk-data (aref (rmail-mime-entity-tagline entity) 1)) 614 (bulk-data (aref (rmail-mime-entity-tagline entity) 1))
629 (body (rmail-mime-entity-body entity)) 615 (body (rmail-mime-entity-body entity))
630 size type to-show) 616 type to-show)
631 (cond (size 617 (cond (size
632 (setq size (string-to-number size))) 618 (setq size (string-to-number size)))
633 ((stringp (aref body 0)) 619 ((stringp (aref body 0))
634 (setq size (length (aref body 0)))) 620 (setq size (length (aref body 0))))
635 (t 621 (t
659 (setcdr bulk-data type) 645 (setcdr bulk-data type)
660 to-show)) 646 to-show))
661 647
662 (defun rmail-mime-insert-bulk (entity) 648 (defun rmail-mime-insert-bulk (entity)
663 "Presentation handler for an attachment MIME entity." 649 "Presentation handler for an attachment MIME entity."
664 ;; Find the default directory for this media type.
665 (let* ((content-type (rmail-mime-entity-type entity)) 650 (let* ((content-type (rmail-mime-entity-type entity))
666 (content-disposition (rmail-mime-entity-disposition entity)) 651 (content-disposition (rmail-mime-entity-disposition entity))
667 (current (aref (rmail-mime-entity-display entity) 0)) 652 (current (aref (rmail-mime-entity-display entity) 0))
668 (new (aref (rmail-mime-entity-display entity) 1)) 653 (new (aref (rmail-mime-entity-display entity) 1))
669 (header (rmail-mime-entity-header entity)) 654 (header (rmail-mime-entity-header entity))
670 (tagline (rmail-mime-entity-tagline entity)) 655 (tagline (rmail-mime-entity-tagline entity))
671 (bulk-data (aref tagline 1)) 656 (bulk-data (aref tagline 1))
672 (body (rmail-mime-entity-body entity)) 657 (body (rmail-mime-entity-body entity))
658 ;; Find the default directory for this media type.
673 (directory (catch 'directory 659 (directory (catch 'directory
674 (dolist (entry rmail-mime-attachment-dirs-alist) 660 (dolist (entry rmail-mime-attachment-dirs-alist)
675 (when (string-match (car entry) (car content-type)) 661 (when (string-match (car entry) (car content-type))
676 (dolist (dir (cdr entry)) 662 (dolist (dir (cdr entry))
677 (when (file-directory-p dir) 663 (when (file-directory-p dir)
708 (if (aref new 0) 694 (if (aref new 0)
709 (rmail-mime-insert-header header))) 695 (rmail-mime-insert-header header)))
710 696
711 ;; tagline 697 ;; tagline
712 (if (eq (aref current 1) (aref new 1)) 698 (if (eq (aref current 1) (aref new 1))
713 (forward-char (- (aref segment 3) (aref segment 2))) 699 (if (or (not (aref current 1))
700 (eq (aref current 2) (aref new 2)))
701 (forward-char (- (aref segment 3) (aref segment 2)))
702 (rmail-mime-update-tagline entity))
714 (if (aref current 1) 703 (if (aref current 1)
715 (delete-char (- (aref segment 3) (aref segment 2)))) 704 (delete-char (- (aref segment 3) (aref segment 2))))
716 (if (aref new 1) 705 (if (aref new 1)
717 (rmail-mime-insert-tagline 706 (rmail-mime-insert-tagline
718 entity 707 entity
719 " file:" 708 " Save:"
720 (list filename 709 (list filename
721 :type 'rmail-mime-save 710 :type 'rmail-mime-save
722 'help-echo "mouse-2, RET: Save attachment" 711 'help-echo "mouse-2, RET: Save attachment"
723 'filename filename 712 'filename filename
724 'directory (file-name-as-directory directory) 713 'directory (file-name-as-directory directory)
725 'data data) 714 'data data)
726 (format " (%.0f%s)" size (car units)) 715 (format " (%.0f%s)" size (car units))
727 (if (cdr bulk-data) 716 ;; We don't need this button because the "type" string of a
728 " ") 717 ;; tagline is the button to do this.
729 (if (cdr bulk-data) 718 ;; (if (cdr bulk-data)
730 (list "Toggle show/hide" 719 ;; " ")
731 :type 'rmail-mime-image 720 ;; (if (cdr bulk-data)
732 'help-echo "mouse-2, RET: Toggle show/hide" 721 ;; (list "Toggle show/hide"
733 'image-type (cdr bulk-data) 722 ;; :type 'rmail-mime-image
734 'image-data data))))) 723 ;; 'help-echo "mouse-2, RET: Toggle show/hide"
724 ;; 'image-type (cdr bulk-data)
725 ;; 'image-data data))
726 )))
735 ;; body 727 ;; body
736 (if (eq (aref current 2) (aref new 2)) 728 (if (eq (aref current 2) (aref new 2))
737 (forward-char (- (aref segment 4) (aref segment 3))) 729 (forward-char (- (aref segment 4) (aref segment 3)))
738 (if (aref current 2) 730 (if (aref current 2)
739 (delete-char (- (aref segment 4) (aref segment 3)))) 731 (delete-char (- (aref segment 4) (aref segment 3))))
880 (if (string-match "text/.*" 872 (if (string-match "text/.*"
881 (car (rmail-mime-entity-type child))) 873 (car (rmail-mime-entity-type child)))
882 (setq second child))))) 874 (setq second child)))))
883 (or best (not second) (setq best second)) 875 (or best (not second) (setq best second))
884 (dolist (child entities) 876 (dolist (child entities)
885 (or (eq best child) 877 (unless (eq best child)
886 (rmail-mime-hidden-mode child t))))) 878 (aset (rmail-mime-entity-body child) 2 nil)
879 (rmail-mime-hidden-mode child)))))
887 entities))) 880 entities)))
888 881
889 (defun test-rmail-mime-multipart-handler () 882 (defun test-rmail-mime-multipart-handler ()
890 "Test of a mail used as an example in RFC 2046." 883 "Test of a mail used as an example in RFC 2046."
891 (let ((mail "From: Nathaniel Borenstein <nsb@bellcore.com> 884 (let ((mail "From: Nathaniel Borenstein <nsb@bellcore.com>
933 (delete-char (- (aref segment 2) (aref segment 1)))) 926 (delete-char (- (aref segment 2) (aref segment 1))))
934 (if (aref new 0) 927 (if (aref new 0)
935 (rmail-mime-insert-header header))) 928 (rmail-mime-insert-header header)))
936 ;; tagline 929 ;; tagline
937 (if (eq (aref current 1) (aref new 1)) 930 (if (eq (aref current 1) (aref new 1))
938 (forward-char (- (aref segment 3) (aref segment 2))) 931 (if (or (not (aref current 1))
932 (eq (aref current 2) (aref new 2)))
933 (forward-char (- (aref segment 3) (aref segment 2)))
934 (rmail-mime-update-tagline entity))
939 (if (aref current 1) 935 (if (aref current 1)
940 (delete-char (- (aref segment 3) (aref segment 2)))) 936 (delete-char (- (aref segment 3) (aref segment 2))))
941 (if (aref new 1) 937 (if (aref new 1)
942 (rmail-mime-insert-tagline entity))) 938 (rmail-mime-insert-tagline entity)))
943 939
944 (put-text-property beg (point) 'rmail-mime-entity entity) 940 (put-text-property beg (point) 'rmail-mime-entity entity)
941
945 ;; body 942 ;; body
946 (if (eq (aref current 2) (aref new 2)) 943 (if (eq (aref current 2) (aref new 2))
947 (forward-char (- (aref segment 4) (aref segment 3))) 944 (forward-char (- (aref segment 4) (aref segment 3)))
948 (if (aref current 2) 945 (dolist (child (rmail-mime-entity-children entity))
949 (delete-char (- (aref segment 4) (aref segment 3)))) 946 (rmail-mime-insert child)))
950 (if (aref new 2) 947 entity))
951 (dolist (child (rmail-mime-entity-children entity))
952 (rmail-mime-insert child))))))
953 948
954 ;;; Main code 949 ;;; Main code
955 950
956 (defun rmail-mime-handle (content-type 951 (defun rmail-mime-handle (content-type
957 content-disposition 952 content-disposition
1008 content-disposition 1003 content-disposition
1009 content-transfer-encoding)))))) 1004 content-transfer-encoding))))))
1010 ;; Everything else is an attachment. 1005 ;; Everything else is an attachment.
1011 (rmail-mime-bulk-handler content-type 1006 (rmail-mime-bulk-handler content-type
1012 content-disposition 1007 content-disposition
1013 content-transfer-encoding))) 1008 content-transfer-encoding))
1009 (save-restriction
1010 (widen)
1011 (let ((entity (get-text-property (1- (point)) 'rmail-mime-entity))
1012 current new)
1013 (when entity
1014 (setq current (aref (rmail-mime-entity-display entity) 0)
1015 new (aref (rmail-mime-entity-display entity) 1))
1016 (dotimes (i 3)
1017 (aset current i (aref new i)))))))
1014 1018
1015 (defun rmail-mime-show (&optional show-headers) 1019 (defun rmail-mime-show (&optional show-headers)
1016 "Handle the current buffer as a MIME message. 1020 "Handle the current buffer as a MIME message.
1017 If SHOW-HEADERS is non-nil, then the headers of the current part 1021 If SHOW-HEADERS is non-nil, then the headers of the current part
1018 will shown as usual for a MIME message. The headers are also 1022 will shown as usual for a MIME message. The headers are also
1053 ;; are not completely so. Hopefully mail-header-parse-* DTRT. 1057 ;; are not completely so. Hopefully mail-header-parse-* DTRT.
1054 (if content-transfer-encoding 1058 (if content-transfer-encoding
1055 (setq content-transfer-encoding (downcase content-transfer-encoding))) 1059 (setq content-transfer-encoding (downcase content-transfer-encoding)))
1056 (setq content-type 1060 (setq content-type
1057 (if content-type 1061 (if content-type
1058 (mail-header-parse-content-type content-type) 1062 (or (mail-header-parse-content-type content-type)
1063 '("text/plain"))
1059 (or default-content-type '("text/plain")))) 1064 (or default-content-type '("text/plain"))))
1060 (setq content-disposition 1065 (setq content-disposition
1061 (if content-disposition 1066 (if content-disposition
1062 (mail-header-parse-content-disposition content-disposition) 1067 (mail-header-parse-content-disposition content-disposition)
1063 ;; If none specified, we are free to choose what we deem 1068 ;; If none specified, we are free to choose what we deem
1181 (aref header 0) (aref header 1))) 1186 (aref header 0) (aref header 1)))
1182 ;; tagline 1187 ;; tagline
1183 (if (aref current 1) 1188 (if (aref current 1)
1184 (delete-char (- (aref segment 3) (aref segment 2)))) 1189 (delete-char (- (aref segment 3) (aref segment 2))))
1185 ;; body 1190 ;; body
1186 (if (eq (aref current 2) (aref new 2)) 1191 (let ((children (rmail-mime-entity-children entity)))
1187 (forward-char (- (aref segment 4) (aref segment 3))) 1192 (if children
1188 (if (aref current 2) 1193 (progn
1189 (delete-char (- (aref segment 4) (aref segment 3)))) 1194 (put-text-property beg (point) 'rmail-mime-entity entity)
1190 (insert-buffer-substring rmail-mime-mbox-buffer 1195 (dolist (child children)
1191 (aref body 0) (aref body 1))) 1196 (rmail-mime-insert child)))
1192 (put-text-property beg (point) 'rmail-mime-entity entity))) 1197 (if (eq (aref current 2) (aref new 2))
1198 (forward-char (- (aref segment 4) (aref segment 3)))
1199 (if (aref current 2)
1200 (delete-char (- (aref segment 4) (aref segment 3))))
1201 (insert-buffer-substring rmail-mime-mbox-buffer
1202 (aref body 0) (aref body 1))
1203 (or (bolp) (insert "\n")))
1204 (put-text-property beg (point) 'rmail-mime-entity entity)))))
1193 (dotimes (i 3) 1205 (dotimes (i 3)
1194 (aset current i (aref new i))))) 1206 (aset current i (aref new i)))))
1195 1207
1196 (define-derived-mode rmail-mime-mode fundamental-mode "RMIME" 1208 (define-derived-mode rmail-mime-mode fundamental-mode "RMIME"
1197 "Major mode used in `rmail-mime' buffers." 1209 "Major mode used in `rmail-mime' buffers."
1215 `rmail-mime-media-type-handlers-alist'. By default, this 1227 `rmail-mime-media-type-handlers-alist'. By default, this
1216 displays text and multipart messages, and offers to download 1228 displays text and multipart messages, and offers to download
1217 attachments as specfied by `rmail-mime-attachment-dirs-alist'." 1229 attachments as specfied by `rmail-mime-attachment-dirs-alist'."
1218 (interactive "P") 1230 (interactive "P")
1219 (if rmail-enable-mime 1231 (if rmail-enable-mime
1220 (if (rmail-mime-message-p) 1232 (with-current-buffer rmail-buffer
1221 (let ((rmail-mime-mbox-buffer rmail-view-buffer) 1233 (if (rmail-mime-message-p)
1222 (rmail-mime-view-buffer rmail-buffer) 1234 (let ((rmail-mime-mbox-buffer rmail-view-buffer)
1223 (entity (get-text-property (point) 'rmail-mime-entity))) 1235 (rmail-mime-view-buffer rmail-buffer)
1224 (if arg 1236 (entity (get-text-property (point) 'rmail-mime-entity)))
1225 (if entity 1237 (if arg
1226 (rmail-mime-toggle-raw entity)) 1238 (if entity
1227 (goto-char (point-min)) 1239 (rmail-mime-toggle-raw entity))
1228 (rmail-mime-toggle-raw 1240 (goto-char (point-min))
1229 (get-text-property (point) 'rmail-mime-entity)))) 1241 (rmail-mime-toggle-raw
1230 (message "Not a MIME message")) 1242 (get-text-property (point) 'rmail-mime-entity))))
1243 (message "Not a MIME message")))
1231 (let* ((data (rmail-apply-in-message rmail-current-message 'buffer-string)) 1244 (let* ((data (rmail-apply-in-message rmail-current-message 'buffer-string))
1232 (buf (get-buffer-create "*RMAIL*")) 1245 (buf (get-buffer-create "*RMAIL*"))
1233 (rmail-mime-mbox-buffer rmail-view-buffer) 1246 (rmail-mime-mbox-buffer rmail-view-buffer)
1234 (rmail-mime-view-buffer buf)) 1247 (rmail-mime-view-buffer buf))
1235 (set-buffer buf) 1248 (set-buffer buf)