Mercurial > emacs
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) |