Mercurial > hg > xemacs-beta
comparison lisp/gnus/gnus-art.el @ 108:360340f9fd5f r20-1b6
Import from CVS: tag r20-1b6
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:18:39 +0200 |
parents | cf808b4c4290 |
children | fe104dbd9147 |
comparison
equal
deleted
inserted
replaced
107:523141596bda | 108:360340f9fd5f |
---|---|
90 | 90 |
91 (defcustom gnus-ignored-headers | 91 (defcustom gnus-ignored-headers |
92 '("^Path:" "^Posting-Version:" "^Article-I.D.:" "^Expires:" | 92 '("^Path:" "^Posting-Version:" "^Article-I.D.:" "^Expires:" |
93 "^Date-Received:" "^References:" "^Control:" "^Xref:" "^Lines:" | 93 "^Date-Received:" "^References:" "^Control:" "^Xref:" "^Lines:" |
94 "^Posted:" "^Relay-Version:" "^Message-ID:" "^Nf-ID:" "^Nf-From:" | 94 "^Posted:" "^Relay-Version:" "^Message-ID:" "^Nf-ID:" "^Nf-From:" |
95 "^Approved:" "^Sender:" "^Received:" "^Mail-from:") | 95 "^Approved:" "^Sender:" "^Received:" "^Mail-from:") |
96 "All headers that match this regexp will be hidden. | 96 "All headers that match this regexp will be hidden. |
97 This variable can also be a list of regexps of headers to be ignored. | 97 This variable can also be a list of regexps of headers to be ignored. |
98 If `gnus-visible-headers' is non-nil, this variable will be ignored." | 98 If `gnus-visible-headers' is non-nil, this variable will be ignored." |
99 :type '(choice :custom-show nil | 99 :type '(choice :custom-show nil |
100 regexp | 100 regexp |
101 (repeat regexp)) | 101 (repeat regexp)) |
102 :group 'gnus-article-hiding) | 102 :group 'gnus-article-hiding) |
103 | 103 |
104 (defcustom gnus-visible-headers | 104 (defcustom gnus-visible-headers |
105 "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-From" | 105 "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-From" |
106 "All headers that do not match this regexp will be hidden. | 106 "All headers that do not match this regexp will be hidden. |
107 This variable can also be a list of regexp of headers to remain visible. | 107 This variable can also be a list of regexp of headers to remain visible. |
108 If this variable is non-nil, `gnus-ignored-headers' will be ignored." | 108 If this variable is non-nil, `gnus-ignored-headers' will be ignored." |
109 :type '(repeat :value-to-internal (lambda (widget value) | 109 :type '(repeat :value-to-internal (lambda (widget value) |
154 :type '(choice integer number function regexp) | 154 :type '(choice integer number function regexp) |
155 :group 'gnus-article-signature) | 155 :group 'gnus-article-signature) |
156 | 156 |
157 (defcustom gnus-hidden-properties '(invisible t intangible t) | 157 (defcustom gnus-hidden-properties '(invisible t intangible t) |
158 "Property list to use for hiding text." | 158 "Property list to use for hiding text." |
159 :type 'sexp | 159 :type 'sexp |
160 :group 'gnus-article-hiding) | 160 :group 'gnus-article-hiding) |
161 | 161 |
162 (defcustom gnus-article-x-face-command | 162 (defcustom gnus-article-x-face-command |
163 "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | xv -quit -" | 163 "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | xv -quit -" |
164 "String or function to be executed to display an X-Face header. | 164 "String or function to be executed to display an X-Face header. |
230 | 230 |
231 (defface gnus-emphasis-bold-italic '((t (:bold t :italic t))) | 231 (defface gnus-emphasis-bold-italic '((t (:bold t :italic t))) |
232 "Face used for displaying bold italic emphasized text (/*word*/)." | 232 "Face used for displaying bold italic emphasized text (/*word*/)." |
233 :group 'gnus-article-emphasis) | 233 :group 'gnus-article-emphasis) |
234 | 234 |
235 (defface gnus-emphasis-underline-bold-italic | 235 (defface gnus-emphasis-underline-bold-italic |
236 '((t (:bold t :italic t :underline t))) | 236 '((t (:bold t :italic t :underline t))) |
237 "Face used for displaying underlined bold italic emphasized text. | 237 "Face used for displaying underlined bold italic emphasized text. |
238 Esample: (_/*word*/_)." | 238 Esample: (_/*word*/_)." |
239 :group 'gnus-article-emphasis) | 239 :group 'gnus-article-emphasis) |
240 | 240 |
247 | 247 |
248 (eval-and-compile | 248 (eval-and-compile |
249 (autoload 'hexl-hex-string-to-integer "hexl") | 249 (autoload 'hexl-hex-string-to-integer "hexl") |
250 (autoload 'timezone-make-date-arpa-standard "timezone") | 250 (autoload 'timezone-make-date-arpa-standard "timezone") |
251 (autoload 'mail-extract-address-components "mail-extr")) | 251 (autoload 'mail-extract-address-components "mail-extr")) |
252 | |
253 (defcustom gnus-article-save-directory gnus-directory | |
254 "*Name of the directory articles will be saved in (default \"~/News\")." | |
255 :group 'gnus-article-saving | |
256 :type 'directory) | |
257 | 252 |
258 (defcustom gnus-save-all-headers t | 253 (defcustom gnus-save-all-headers t |
259 "*If non-nil, don't remove any headers before saving." | 254 "*If non-nil, don't remove any headers before saving." |
260 :group 'gnus-article-saving | 255 :group 'gnus-article-saving |
261 :type 'boolean) | 256 :type 'boolean) |
419 "Face used for highlighting a signature in the article buffer." | 414 "Face used for highlighting a signature in the article buffer." |
420 :type 'face | 415 :type 'face |
421 :group 'gnus-article-highlight | 416 :group 'gnus-article-highlight |
422 :group 'gnus-article-signature) | 417 :group 'gnus-article-signature) |
423 | 418 |
424 (defface gnus-header-from-face | 419 (defface gnus-header-from-face |
425 '((((class color) | 420 '((((class color) |
426 (background dark)) | 421 (background dark)) |
427 (:foreground "light blue" :bold t :italic t)) | 422 (:foreground "spring green" :bold t :italic t)) |
428 (((class color) | 423 (((class color) |
429 (background light)) | 424 (background light)) |
430 (:foreground "MidnightBlue" :bold t :italic t)) | 425 (:foreground "indianred" :bold t :italic t)) |
431 (t | 426 (t |
432 (:bold t :italic t))) | 427 (:bold t :italic t))) |
433 "Face used for displaying from headers." | 428 "Face used for displaying from headers." |
434 :group 'gnus-article-headers | 429 :group 'gnus-article-headers |
435 :group 'gnus-article-highlight) | 430 :group 'gnus-article-highlight) |
436 | 431 |
437 (defface gnus-header-subject-face | 432 (defface gnus-header-subject-face |
438 '((((class color) | 433 '((((class color) |
439 (background dark)) | 434 (background dark)) |
440 (:foreground "pink" :bold t :italic t)) | 435 (:foreground "SeaGreen3" :bold t :italic t)) |
441 (((class color) | 436 (((class color) |
442 (background light)) | 437 (background light)) |
443 (:foreground "firebrick" :bold t :italic t)) | 438 (:foreground "firebrick" :bold t :italic t)) |
444 (t | 439 (t |
445 (:bold t :italic t))) | 440 (:bold t :italic t))) |
446 "Face used for displaying subject headers." | 441 "Face used for displaying subject headers." |
447 :group 'gnus-article-headers | 442 :group 'gnus-article-headers |
448 :group 'gnus-article-highlight) | 443 :group 'gnus-article-highlight) |
449 | 444 |
450 (defface gnus-header-newsgroups-face | 445 (defface gnus-header-newsgroups-face |
451 '((((class color) | 446 '((((class color) |
452 (background dark)) | 447 (background dark)) |
453 (:foreground "yellow" :bold t :italic t)) | 448 (:foreground "yellow" :bold t :italic t)) |
454 (((class color) | 449 (((class color) |
455 (background light)) | 450 (background light)) |
456 (:foreground "indianred" :bold t :italic t)) | 451 (:foreground "MidnightBlue" :bold t :italic t)) |
457 (t | 452 (t |
458 (:bold t :italic t))) | 453 (:bold t :italic t))) |
459 "Face used for displaying newsgroups headers." | 454 "Face used for displaying newsgroups headers." |
460 :group 'gnus-article-headers | 455 :group 'gnus-article-headers |
461 :group 'gnus-article-highlight) | 456 :group 'gnus-article-highlight) |
462 | 457 |
463 (defface gnus-header-name-face | 458 (defface gnus-header-name-face |
464 '((((class color) | 459 '((((class color) |
465 (background dark)) | 460 (background dark)) |
466 (:foreground "cyan" :bold t)) | 461 (:foreground "SeaGreen")) |
467 (((class color) | 462 (((class color) |
468 (background light)) | 463 (background light)) |
469 (:foreground "DarkGreen" :bold t)) | 464 (:foreground "maroon")) |
470 (t | 465 (t |
471 (:bold t))) | 466 (:bold t))) |
472 "Face used for displaying header names." | 467 "Face used for displaying header names." |
473 :group 'gnus-article-headers | 468 :group 'gnus-article-headers |
474 :group 'gnus-article-highlight) | 469 :group 'gnus-article-highlight) |
475 | 470 |
477 '((((class color) | 472 '((((class color) |
478 (background dark)) | 473 (background dark)) |
479 (:foreground "forest green" :italic t)) | 474 (:foreground "forest green" :italic t)) |
480 (((class color) | 475 (((class color) |
481 (background light)) | 476 (background light)) |
482 (:foreground "DarkGreen" :italic t)) | 477 (:foreground "indianred4" :italic t)) |
483 (t | 478 (t |
484 (:italic t))) "Face used for displaying header content." | 479 (:italic t))) "Face used for displaying header content." |
485 :group 'gnus-article-headers | 480 :group 'gnus-article-headers |
486 :group 'gnus-article-highlight) | 481 :group 'gnus-article-highlight) |
487 | 482 |
488 (defcustom gnus-header-face-alist | 483 (defcustom gnus-header-face-alist |
490 ("Subject" nil gnus-header-subject-face) | 485 ("Subject" nil gnus-header-subject-face) |
491 ("Newsgroups:.*," nil gnus-header-newsgroups-face) | 486 ("Newsgroups:.*," nil gnus-header-newsgroups-face) |
492 ("" gnus-header-name-face gnus-header-content-face)) | 487 ("" gnus-header-name-face gnus-header-content-face)) |
493 "Controls highlighting of article header. | 488 "Controls highlighting of article header. |
494 | 489 |
495 An alist of the form (HEADER NAME CONTENT). | 490 An alist of the form (HEADER NAME CONTENT). |
496 | 491 |
497 HEADER is a regular expression which should match the name of an | 492 HEADER is a regular expression which should match the name of an |
498 header header and NAME and CONTENT are either face names or nil. | 493 header header and NAME and CONTENT are either face names or nil. |
499 | 494 |
500 The name of each header field will be displayed using the face | 495 The name of each header field will be displayed using the face |
533 | 528 |
534 (defsubst gnus-article-hide-text (b e props) | 529 (defsubst gnus-article-hide-text (b e props) |
535 "Set text PROPS on the B to E region, extending `intangible' 1 past B." | 530 "Set text PROPS on the B to E region, extending `intangible' 1 past B." |
536 (add-text-properties b e props) | 531 (add-text-properties b e props) |
537 (when (memq 'intangible props) | 532 (when (memq 'intangible props) |
538 (put-text-property | 533 (put-text-property |
539 (max (1- b) (point-min)) | 534 (max (1- b) (point-min)) |
540 b 'intangible (cddr (memq 'intangible props))))) | 535 b 'intangible (cddr (memq 'intangible props))))) |
541 | 536 |
542 (defsubst gnus-article-unhide-text (b e) | 537 (defsubst gnus-article-unhide-text (b e) |
543 "Remove hidden text properties from region between B and E." | 538 "Remove hidden text properties from region between B and E." |
648 ;; article buffer. | 643 ;; article buffer. |
649 (goto-char (point-min)) | 644 (goto-char (point-min)) |
650 (while (re-search-forward "^[^ \t]*:" nil t) | 645 (while (re-search-forward "^[^ \t]*:" nil t) |
651 (beginning-of-line) | 646 (beginning-of-line) |
652 ;; Mark the rank of the header. | 647 ;; Mark the rank of the header. |
653 (put-text-property | 648 (put-text-property |
654 (point) (1+ (point)) 'message-rank | 649 (point) (1+ (point)) 'message-rank |
655 (if (or (and visible (looking-at visible)) | 650 (if (or (and visible (looking-at visible)) |
656 (and ignored | 651 (and ignored |
657 (not (looking-at ignored)))) | 652 (not (looking-at ignored)))) |
658 (gnus-article-header-rank) | 653 (gnus-article-header-rank) |
659 (+ 2 max))) | 654 (+ 2 max))) |
660 (forward-line 1)) | 655 (forward-line 1)) |
661 (message-sort-headers-1) | 656 (message-sort-headers-1) |
662 (when (setq beg (text-property-any | 657 (when (setq beg (text-property-any |
663 (point-min) (point-max) 'message-rank (+ 2 max))) | 658 (point-min) (point-max) 'message-rank (+ 2 max))) |
664 ;; We make the unwanted headers invisible. | 659 ;; We make the unwanted headers invisible. |
665 (if delete | 660 (if delete |
666 (delete-region beg (point-max)) | 661 (delete-region beg (point-max)) |
667 ;; Suggested by Sudish Joseph <joseph@cis.ohio-state.edu>. | 662 ;; Suggested by Sudish Joseph <joseph@cis.ohio-state.edu>. |
691 ((eq elem 'empty) | 686 ((eq elem 'empty) |
692 (while (re-search-forward "^[^:]+:[ \t]*\n[^ \t]" nil t) | 687 (while (re-search-forward "^[^:]+:[ \t]*\n[^ \t]" nil t) |
693 (forward-line -1) | 688 (forward-line -1) |
694 (gnus-article-hide-text-type | 689 (gnus-article-hide-text-type |
695 (progn (beginning-of-line) (point)) | 690 (progn (beginning-of-line) (point)) |
696 (progn | 691 (progn |
697 (end-of-line) | 692 (end-of-line) |
698 (if (re-search-forward "^[^ \t]" nil t) | 693 (if (re-search-forward "^[^ \t]" nil t) |
699 (match-beginning 0) | 694 (match-beginning 0) |
700 (point-max))) | 695 (point-max))) |
701 'boring-headers))) | 696 'boring-headers))) |
715 (let ((from (message-fetch-field "from")) | 710 (let ((from (message-fetch-field "from")) |
716 (reply-to (message-fetch-field "reply-to"))) | 711 (reply-to (message-fetch-field "reply-to"))) |
717 (when (and | 712 (when (and |
718 from reply-to | 713 from reply-to |
719 (ignore-errors | 714 (ignore-errors |
720 (equal | 715 (equal |
721 (nth 1 (mail-extract-address-components from)) | 716 (nth 1 (mail-extract-address-components from)) |
722 (nth 1 (mail-extract-address-components reply-to))))) | 717 (nth 1 (mail-extract-address-components reply-to))))) |
723 (gnus-article-hide-header "reply-to")))) | 718 (gnus-article-hide-header "reply-to")))) |
724 ((eq elem 'date) | 719 ((eq elem 'date) |
725 (let ((date (message-fetch-field "date"))) | 720 (let ((date (message-fetch-field "date"))) |
732 (save-excursion | 727 (save-excursion |
733 (goto-char (point-min)) | 728 (goto-char (point-min)) |
734 (when (re-search-forward (concat "^" header ":") nil t) | 729 (when (re-search-forward (concat "^" header ":") nil t) |
735 (gnus-article-hide-text-type | 730 (gnus-article-hide-text-type |
736 (progn (beginning-of-line) (point)) | 731 (progn (beginning-of-line) (point)) |
737 (progn | 732 (progn |
738 (end-of-line) | 733 (end-of-line) |
739 (if (re-search-forward "^[^ \t]" nil t) | 734 (if (re-search-forward "^[^ \t]" nil t) |
740 (match-beginning 0) | 735 (match-beginning 0) |
741 (point-max))) | 736 (point-max))) |
742 'boring-headers)))) | 737 'boring-headers)))) |
751 (let ((next (following-char)) | 746 (let ((next (following-char)) |
752 (previous (char-after (- (point) 2)))) | 747 (previous (char-after (- (point) 2)))) |
753 ;; We do the boldification/underlining by hiding the | 748 ;; We do the boldification/underlining by hiding the |
754 ;; overstrikes and putting the proper text property | 749 ;; overstrikes and putting the proper text property |
755 ;; on the letters. | 750 ;; on the letters. |
756 (cond | 751 (cond |
757 ((eq next previous) | 752 ((eq next previous) |
758 (gnus-article-hide-text-type (- (point) 2) (point) 'overstrike) | 753 (gnus-article-hide-text-type (- (point) 2) (point) 'overstrike) |
759 (put-text-property (point) (1+ (point)) 'face 'bold)) | 754 (put-text-property (point) (1+ (point)) 'face 'bold)) |
760 ((eq next ?_) | 755 ((eq next ?_) |
761 (gnus-article-hide-text-type (1- (point)) (1+ (point)) 'overstrike) | 756 (gnus-article-hide-text-type (1- (point)) (1+ (point)) 'overstrike) |
861 (save-restriction | 856 (save-restriction |
862 (narrow-to-region | 857 (narrow-to-region |
863 (goto-char (point-min)) | 858 (goto-char (point-min)) |
864 (or (search-forward "\n\n" nil t) (point-max))) | 859 (or (search-forward "\n\n" nil t) (point-max))) |
865 (goto-char (point-min)) | 860 (goto-char (point-min)) |
866 (while (re-search-forward | 861 (while (re-search-forward |
867 "=\\?iso-8859-1\\?q\\?\\([^?\t\n]*\\)\\?=" nil t) | 862 "=\\?iso-8859-1\\?q\\?\\([^?\t\n]*\\)\\?=" nil t) |
868 (setq string (match-string 1)) | 863 (setq string (match-string 1)) |
869 (save-restriction | 864 (save-restriction |
870 (narrow-to-region (match-beginning 0) (match-end 0)) | 865 (narrow-to-region (match-beginning 0) (match-end 0)) |
871 (delete-region (point-min) (point-max)) | 866 (delete-region (point-min) (point-max)) |
872 (insert string) | 867 (insert string) |
873 (article-mime-decode-quoted-printable | 868 (article-mime-decode-quoted-printable |
874 (goto-char (point-min)) (point-max)) | 869 (goto-char (point-min)) (point-max)) |
875 (subst-char-in-region (point-min) (point-max) ?_ ? ) | 870 (subst-char-in-region (point-min) (point-max) ?_ ? ) |
876 (goto-char (point-max))) | 871 (goto-char (point-max))) |
877 (goto-char (point-min)))))) | 872 (goto-char (point-min)))))) |
878 | 873 |
896 (article-mime-decode-quoted-printable (point) (point-max)))))) | 891 (article-mime-decode-quoted-printable (point) (point-max)))))) |
897 | 892 |
898 (defun article-mime-decode-quoted-printable-buffer () | 893 (defun article-mime-decode-quoted-printable-buffer () |
899 "Decode Quoted-Printable in the current buffer." | 894 "Decode Quoted-Printable in the current buffer." |
900 (article-mime-decode-quoted-printable (point-min) (point-max))) | 895 (article-mime-decode-quoted-printable (point-min) (point-max))) |
901 | 896 |
902 (defun article-mime-decode-quoted-printable (from to) | 897 (defun article-mime-decode-quoted-printable (from to) |
903 "Decode Quoted-Printable in the region between FROM and TO." | 898 "Decode Quoted-Printable in the region between FROM and TO." |
904 (interactive "r") | 899 (interactive "r") |
905 (goto-char from) | 900 (goto-char from) |
906 (while (search-forward "=" to t) | 901 (while (search-forward "=" to t) |
947 ;; Hide "- " PGP quotation markers. | 942 ;; Hide "- " PGP quotation markers. |
948 (when (and beg end) | 943 (when (and beg end) |
949 (narrow-to-region beg end) | 944 (narrow-to-region beg end) |
950 (goto-char (point-min)) | 945 (goto-char (point-min)) |
951 (while (re-search-forward "^- " nil t) | 946 (while (re-search-forward "^- " nil t) |
952 (gnus-article-hide-text-type | 947 (gnus-article-hide-text-type |
953 (match-beginning 0) (match-end 0) 'pgp)) | 948 (match-beginning 0) (match-end 0) 'pgp)) |
954 (widen)))))) | 949 (widen)))))) |
955 | 950 |
956 (defun article-hide-pem (&optional arg) | 951 (defun article-hide-pem (&optional arg) |
957 "Toggle hiding of any PEM headers and signatures in the current article. | 952 "Toggle hiding of any PEM headers and signatures in the current article. |
989 (unless (gnus-article-check-hidden-text 'signature arg) | 984 (unless (gnus-article-check-hidden-text 'signature arg) |
990 (save-excursion | 985 (save-excursion |
991 (save-restriction | 986 (save-restriction |
992 (let ((buffer-read-only nil)) | 987 (let ((buffer-read-only nil)) |
993 (when (gnus-article-narrow-to-signature) | 988 (when (gnus-article-narrow-to-signature) |
994 (gnus-article-hide-text-type | 989 (gnus-article-hide-text-type |
995 (point-min) (point-max) 'signature))))))) | 990 (point-min) (point-max) 'signature))))))) |
996 | 991 |
997 (defun article-strip-leading-blank-lines () | 992 (defun article-strip-leading-blank-lines () |
998 "Remove all blank lines from the beginning of the article." | 993 "Remove all blank lines from the beginning of the article." |
999 (interactive) | 994 (interactive) |
1041 (let ((pcinfo (car (last mime::preview/content-list)))) | 1036 (let ((pcinfo (car (last mime::preview/content-list)))) |
1042 (ignore-errors | 1037 (ignore-errors |
1043 (narrow-to-region | 1038 (narrow-to-region |
1044 (funcall (intern "mime::preview-content-info/point-min") pcinfo) | 1039 (funcall (intern "mime::preview-content-info/point-min") pcinfo) |
1045 (point-max))))) | 1040 (point-max))))) |
1046 | 1041 |
1047 (when (gnus-article-search-signature) | 1042 (when (gnus-article-search-signature) |
1048 (forward-line 1) | 1043 (forward-line 1) |
1049 ;; Check whether we have some limits to what we consider | 1044 ;; Check whether we have some limits to what we consider |
1050 ;; to be a signature. | 1045 ;; to be a signature. |
1051 (let ((limits (if (listp gnus-signature-limit) gnus-signature-limit | 1046 (let ((limits (if (listp gnus-signature-limit) gnus-signature-limit |
1175 (defun article-date-ut (&optional type highlight header) | 1170 (defun article-date-ut (&optional type highlight header) |
1176 "Convert DATE date to universal time in the current article. | 1171 "Convert DATE date to universal time in the current article. |
1177 If TYPE is `local', convert to local time; if it is `lapsed', output | 1172 If TYPE is `local', convert to local time; if it is `lapsed', output |
1178 how much time has lapsed since DATE." | 1173 how much time has lapsed since DATE." |
1179 (interactive (list 'ut t)) | 1174 (interactive (list 'ut t)) |
1180 (let* ((header (or header | 1175 (let* ((header (or header |
1181 (mail-header-date gnus-current-headers) | 1176 (mail-header-date gnus-current-headers) |
1182 (message-fetch-field "date") | 1177 (message-fetch-field "date") |
1183 "")) | 1178 "")) |
1184 (date (if (vectorp header) (mail-header-date header) | 1179 (date (if (vectorp header) (mail-header-date header) |
1185 header)) | 1180 header)) |
1282 ;; It's big enough, so we output it. | 1277 ;; It's big enough, so we output it. |
1283 (setq sec (- sec (* num (cdr unit)))) | 1278 (setq sec (- sec (* num (cdr unit)))) |
1284 (prog1 | 1279 (prog1 |
1285 (concat (if prev ", " "") (int-to-string | 1280 (concat (if prev ", " "") (int-to-string |
1286 (floor num)) | 1281 (floor num)) |
1287 " " (symbol-name (car unit)) | 1282 " " (symbol-name (car unit)) |
1288 (if (> num 1) "s" "")) | 1283 (if (> num 1) "s" "")) |
1289 (setq prev t)))) | 1284 (setq prev t)))) |
1290 article-time-units "") | 1285 article-time-units "") |
1291 ;; If dates are odd, then it might appear like the | 1286 ;; If dates are odd, then it might appear like the |
1292 ;; article was sent in the future. | 1287 ;; article was sent in the future. |
1383 (t file))) | 1378 (t file))) |
1384 (gnus-number-of-articles-to-be-saved | 1379 (gnus-number-of-articles-to-be-saved |
1385 (when (eq gnus-prompt-before-saving t) | 1380 (when (eq gnus-prompt-before-saving t) |
1386 num))) ; Magic | 1381 num))) ; Magic |
1387 (set-buffer gnus-summary-buffer) | 1382 (set-buffer gnus-summary-buffer) |
1388 (funcall gnus-default-article-saver filename))))) | 1383 (funcall gnus-default-article-saver filename))))) |
1389 | 1384 |
1390 (defun gnus-read-save-file-name (prompt default-name &optional filename) | 1385 (defun gnus-read-save-file-name (prompt default-name &optional filename) |
1391 (cond | 1386 (cond |
1392 ((eq filename 'default) | 1387 ((eq filename 'default) |
1393 default-name) | 1388 default-name) |
1555 (gnus-set-global-variables) | 1550 (gnus-set-global-variables) |
1556 (setq command | 1551 (setq command |
1557 (cond ((eq command 'default) | 1552 (cond ((eq command 'default) |
1558 gnus-last-shell-command) | 1553 gnus-last-shell-command) |
1559 (command command) | 1554 (command command) |
1560 (t (read-string | 1555 (t (read-string |
1561 (format | 1556 (format |
1562 "Shell command on %s: " | 1557 "Shell command on %s: " |
1563 (if (and gnus-number-of-articles-to-be-saved | 1558 (if (and gnus-number-of-articles-to-be-saved |
1564 (> gnus-number-of-articles-to-be-saved 1)) | 1559 (> gnus-number-of-articles-to-be-saved 1)) |
1565 (format "these %d articles" | 1560 (format "these %d articles" |
1647 (if (consp func) | 1642 (if (consp func) |
1648 (setq afunc (car func) | 1643 (setq afunc (car func) |
1649 gfunc (cdr func)) | 1644 gfunc (cdr func)) |
1650 (setq afunc func | 1645 (setq afunc func |
1651 gfunc (intern (format "gnus-%s" func)))) | 1646 gfunc (intern (format "gnus-%s" func)))) |
1652 (fset gfunc | 1647 (fset gfunc |
1653 (if (not (fboundp afunc)) | 1648 (if (not (fboundp afunc)) |
1654 nil | 1649 nil |
1655 `(lambda (&optional interactive &rest args) | 1650 `(lambda (&optional interactive &rest args) |
1656 ,(documentation afunc t) | 1651 ,(documentation afunc t) |
1657 (interactive (list t)) | 1652 (interactive (list t)) |
2246 (buffer-name (get-buffer gnus-summary-buffer))) | 2241 (buffer-name (get-buffer gnus-summary-buffer))) |
2247 (save-excursion | 2242 (save-excursion |
2248 (set-buffer gnus-summary-buffer) | 2243 (set-buffer gnus-summary-buffer) |
2249 (let ((header (gnus-summary-article-header article))) | 2244 (let ((header (gnus-summary-article-header article))) |
2250 (when (< article 0) | 2245 (when (< article 0) |
2251 (cond | 2246 (cond |
2252 ((memq article gnus-newsgroup-sparse) | 2247 ((memq article gnus-newsgroup-sparse) |
2253 ;; This is a sparse gap article. | 2248 ;; This is a sparse gap article. |
2254 (setq do-update-line article) | 2249 (setq do-update-line article) |
2255 (setq article (mail-header-id header)) | 2250 (setq article (mail-header-id header)) |
2256 (let ((gnus-override-method gnus-refer-article-method)) | 2251 (let ((gnus-override-method gnus-refer-article-method)) |
2262 (setq article (mail-header-id header))) | 2257 (setq article (mail-header-id header))) |
2263 (t | 2258 (t |
2264 ;; It is an extracted pseudo-article. | 2259 ;; It is an extracted pseudo-article. |
2265 (setq article 'pseudo) | 2260 (setq article 'pseudo) |
2266 (gnus-request-pseudo-article header)))) | 2261 (gnus-request-pseudo-article header)))) |
2267 | 2262 |
2268 (let ((method (gnus-find-method-for-group | 2263 (let ((method (gnus-find-method-for-group |
2269 gnus-newsgroup-name))) | 2264 gnus-newsgroup-name))) |
2270 (if (not (eq (car method) 'nneething)) | 2265 (if (not (eq (car method) 'nneething)) |
2271 () | 2266 () |
2272 (let ((dir (concat (file-name-as-directory (nth 1 method)) | 2267 (let ((dir (concat (file-name-as-directory (nth 1 method)) |
2273 (mail-header-subject header)))) | 2268 (mail-header-subject header)))) |
2317 (gnus-kill-all-overlays) | 2312 (gnus-kill-all-overlays) |
2318 (when (gnus-request-article article group (current-buffer)) | 2313 (when (gnus-request-article article group (current-buffer)) |
2319 (when (numberp article) | 2314 (when (numberp article) |
2320 (gnus-async-prefetch-next group article gnus-summary-buffer) | 2315 (gnus-async-prefetch-next group article gnus-summary-buffer) |
2321 (when gnus-keep-backlog | 2316 (when gnus-keep-backlog |
2322 (gnus-backlog-enter-article | 2317 (gnus-backlog-enter-article |
2323 group article (current-buffer)))) | 2318 group article (current-buffer)))) |
2324 'article))) | 2319 'article))) |
2325 ;; It was a pseudo. | 2320 ;; It was a pseudo. |
2326 (t article))) | 2321 (t article))) |
2327 | 2322 |
2341 (gnus-add-current-to-buffer-list)) | 2336 (gnus-add-current-to-buffer-list)) |
2342 (let (buffer-read-only) | 2337 (let (buffer-read-only) |
2343 (erase-buffer) | 2338 (erase-buffer) |
2344 (insert-buffer-substring gnus-article-buffer)) | 2339 (insert-buffer-substring gnus-article-buffer)) |
2345 (setq gnus-original-article (cons group article)))) | 2340 (setq gnus-original-article (cons group article)))) |
2346 | 2341 |
2347 ;; Update sparse articles. | 2342 ;; Update sparse articles. |
2348 (when (and do-update-line | 2343 (when (and do-update-line |
2349 (or (numberp article) | 2344 (or (numberp article) |
2350 (stringp article))) | 2345 (stringp article))) |
2351 (let ((buf (current-buffer))) | 2346 (let ((buf (current-buffer))) |
2367 | 2362 |
2368 (defvar gnus-article-edit-done-function nil) | 2363 (defvar gnus-article-edit-done-function nil) |
2369 | 2364 |
2370 (defvar gnus-article-edit-mode-map nil) | 2365 (defvar gnus-article-edit-mode-map nil) |
2371 | 2366 |
2372 (unless gnus-article-edit-mode-map | 2367 (unless gnus-article-edit-mode-map |
2373 (setq gnus-article-edit-mode-map (copy-keymap text-mode-map)) | 2368 (setq gnus-article-edit-mode-map (copy-keymap text-mode-map)) |
2374 | 2369 |
2375 (gnus-define-keys gnus-article-edit-mode-map | 2370 (gnus-define-keys gnus-article-edit-mode-map |
2376 "\C-c\C-c" gnus-article-edit-done | 2371 "\C-c\C-c" gnus-article-edit-done |
2377 "\C-c\C-k" gnus-article-edit-exit) | 2372 "\C-c\C-k" gnus-article-edit-exit) |
2450 (insert buf) | 2445 (insert buf) |
2451 (let ((winconf gnus-prev-winconf)) | 2446 (let ((winconf gnus-prev-winconf)) |
2452 (gnus-article-mode) | 2447 (gnus-article-mode) |
2453 ;; The cache and backlog have to be flushed somewhat. | 2448 ;; The cache and backlog have to be flushed somewhat. |
2454 (when gnus-use-cache | 2449 (when gnus-use-cache |
2455 (gnus-cache-update-article | 2450 (gnus-cache-update-article |
2456 (car gnus-article-current) (cdr gnus-article-current))) | 2451 (car gnus-article-current) (cdr gnus-article-current))) |
2457 (when gnus-keep-backlog | 2452 (when gnus-keep-backlog |
2458 (gnus-backlog-remove-article | 2453 (gnus-backlog-remove-article |
2459 (car gnus-article-current) (cdr gnus-article-current))) | 2454 (car gnus-article-current) (cdr gnus-article-current))) |
2460 ;; Flush original article as well. | 2455 ;; Flush original article as well. |
2461 (save-excursion | 2456 (save-excursion |
2462 (when (get-buffer gnus-original-article-buffer) | 2457 (when (get-buffer gnus-original-article-buffer) |
2463 (set-buffer gnus-original-article-buffer) | 2458 (set-buffer gnus-original-article-buffer) |
2467 (let ((buf (current-buffer))) | 2462 (let ((buf (current-buffer))) |
2468 (set-buffer curbuf) | 2463 (set-buffer curbuf) |
2469 (set-window-start (get-buffer-window (current-buffer)) window-start) | 2464 (set-window-start (get-buffer-window (current-buffer)) window-start) |
2470 (goto-char p) | 2465 (goto-char p) |
2471 (set-buffer buf))))) | 2466 (set-buffer buf))))) |
2472 | 2467 |
2473 (defun gnus-article-edit-full-stops () | 2468 (defun gnus-article-edit-full-stops () |
2474 "Interactively repair spacing at end of sentences." | 2469 "Interactively repair spacing at end of sentences." |
2475 (interactive) | 2470 (interactive) |
2476 (save-excursion | 2471 (save-excursion |
2477 (goto-char (point-min)) | 2472 (goto-char (point-min)) |
2478 (search-forward-regexp "^$" nil t) | 2473 (search-forward-regexp "^$" nil t) |
2479 (let ((case-fold-search nil)) | 2474 (let ((case-fold-search nil)) |
2480 (query-replace-regexp "\\([.!?][])}]* \\)\\([[({A-Z]\\)" "\\1 \\2")))) | 2475 (query-replace-regexp "\\([.!?][])}]* \\)\\([[({A-Z]\\)" "\\1 \\2")))) |
2481 | 2476 |
2482 ;;; | 2477 ;;; |
2483 ;;; Article highlights | 2478 ;;; Article highlights |
2484 ;;; | 2479 ;;; |
2485 | 2480 |
2486 ;; Written by Per Abrahamsen <abraham@iesd.auc.dk>. | 2481 ;; Written by Per Abrahamsen <abraham@iesd.auc.dk>. |
2487 | 2482 |
2490 (defcustom gnus-button-url-regexp "\\b\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\):\\(//[-a-zA-Z0-9_.]+:[0-9]*\\)?\\([-a-zA-Z0-9_=!?#$@~`%&*+|\\/:;.,]\\|\\w\\)+\\([-a-zA-Z0-9_=#$@~`%&*+|\\/]\\|\\w\\)" | 2485 (defcustom gnus-button-url-regexp "\\b\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\):\\(//[-a-zA-Z0-9_.]+:[0-9]*\\)?\\([-a-zA-Z0-9_=!?#$@~`%&*+|\\/:;.,]\\|\\w\\)+\\([-a-zA-Z0-9_=#$@~`%&*+|\\/]\\|\\w\\)" |
2491 "Regular expression that matches URLs." | 2486 "Regular expression that matches URLs." |
2492 :group 'gnus-article-buttons | 2487 :group 'gnus-article-buttons |
2493 :type 'regexp) | 2488 :type 'regexp) |
2494 | 2489 |
2495 (defcustom gnus-button-alist | 2490 (defcustom gnus-button-alist |
2496 `(("<\\(url: ?\\)?news:\\([^>\n\t ]*@[^>\n\t ]*\\)>" 0 t | 2491 `(("<\\(url: ?\\)?news:\\([^>\n\t ]*@[^>\n\t ]*\\)>" 0 t |
2497 gnus-button-message-id 2) | 2492 gnus-button-message-id 2) |
2498 ("\\bnews:\\([^>\n\t ]*@[^>\n\t ]*+\\)" 0 t gnus-button-message-id 1) | 2493 ("\\bnews:\\([^>\n\t ]*@[^>\n\t ]*+\\)" 0 t gnus-button-message-id 1) |
2499 ("\\(\\b<\\(url: ?\\)?news:\\(//\\)?\\([^>\n\t ]*\\)>\\)" 1 t | 2494 ("\\(\\b<\\(url: ?\\)?news:\\(//\\)?\\([^>\n\t ]*\\)>\\)" 1 t |
2500 gnus-button-fetch-group 4) | 2495 gnus-button-fetch-group 4) |
2501 ("\\bnews:\\(//\\)?\\([^>\n\t ]+\\)" 0 t gnus-button-fetch-group 2) | 2496 ("\\bnews:\\(//\\)?\\([^>\n\t ]+\\)" 0 t gnus-button-fetch-group 2) |
2502 ("\\bin\\( +article\\)? +\\(<\\([^\n @<>]+@[^\n @<>]+\\)>\\)" 2 | 2497 ("\\bin\\( +article\\)? +\\(<\\([^\n @<>]+@[^\n @<>]+\\)>\\)" 2 |
2503 t gnus-button-message-id 3) | 2498 t gnus-button-message-id 3) |
2504 ("\\(<URL: *\\)mailto: *\\([^> \n\t]+\\)>" 0 t gnus-url-mailto 1) | 2499 ("\\(<URL: *\\)mailto: *\\([^> \n\t]+\\)>" 0 t gnus-url-mailto 1) |
2505 ("\\bmailto:\\([^ \n\t]+\\)" 0 t gnus-url-mailto 2) | 2500 ("\\bmailto:\\([^ \n\t]+\\)" 0 t gnus-url-mailto 2) |
2506 ;; This is how URLs _should_ be embedded in text... | 2501 ;; This is how URLs _should_ be embedded in text... |
2507 ("<URL: *\\([^>]*\\)>" 0 t gnus-button-embedded-url 1) | 2502 ("<URL: *\\([^>]*\\)>" 0 t gnus-button-embedded-url 1) |
2511 | 2506 |
2512 Each entry has the form (REGEXP BUTTON FORM CALLBACK PAR...), where | 2507 Each entry has the form (REGEXP BUTTON FORM CALLBACK PAR...), where |
2513 REGEXP: is the string matching text around the button, | 2508 REGEXP: is the string matching text around the button, |
2514 BUTTON: is the number of the regexp grouping actually matching the button, | 2509 BUTTON: is the number of the regexp grouping actually matching the button, |
2515 FORM: is a lisp expression which must eval to true for the button to | 2510 FORM: is a lisp expression which must eval to true for the button to |
2516 be added, | 2511 be added, |
2517 CALLBACK: is the function to call when the user push this button, and each | 2512 CALLBACK: is the function to call when the user push this button, and each |
2518 PAR: is a number of a regexp grouping whose text will be passed to CALLBACK. | 2513 PAR: is a number of a regexp grouping whose text will be passed to CALLBACK. |
2519 | 2514 |
2520 CALLBACK can also be a variable, in that case the value of that | 2515 CALLBACK can also be a variable, in that case the value of that |
2521 variable it the real callback function." | 2516 variable it the real callback function." |
2522 :group 'gnus-article-buttons | 2517 :group 'gnus-article-buttons |
2523 :type '(repeat (list regexp | 2518 :type '(repeat (list regexp |
2524 (integer :tag "Button") | 2519 (integer :tag "Button") |
2525 (sexp :tag "Form") | 2520 (sexp :tag "Form") |
2526 (function :tag "Callback") | 2521 (function :tag "Callback") |
2527 (repeat :tag "Par" | 2522 (repeat :tag "Par" |
2528 :inline t | 2523 :inline t |
2529 (integer :tag "Regexp group"))))) | 2524 (integer :tag "Regexp group"))))) |
2530 | 2525 |
2531 (defcustom gnus-header-button-alist | 2526 (defcustom gnus-header-button-alist |
2532 `(("^\\(References\\|Message-I[Dd]\\):" "<[^>]+>" | 2527 `(("^\\(References\\|Message-I[Dd]\\):" "<[^>]+>" |
2533 0 t gnus-button-message-id 0) | 2528 0 t gnus-button-message-id 0) |
2534 ("^\\(From\\|Reply-To\\):" ": *\\(.+\\)$" 1 t gnus-button-reply 1) | 2529 ("^\\(From\\|Reply-To\\):" ": *\\(.+\\)$" 1 t gnus-button-reply 1) |
2535 ("^\\(Cc\\|To\\):" "[^ \t\n<>,()\"]+@[^ \t\n<>,()\"]+" | 2530 ("^\\(Cc\\|To\\):" "[^ \t\n<>,()\"]+@[^ \t\n<>,()\"]+" |
2536 0 t gnus-button-mailto 0) | 2531 0 t gnus-button-mailto 0) |
2537 ("^X-[Uu][Rr][Ll]:" ,gnus-button-url-regexp 0 t gnus-button-url 0) | 2532 ("^X-[Uu][Rr][Ll]:" ,gnus-button-url-regexp 0 t gnus-button-url 0) |
2538 ("^[^:]+:" ,gnus-button-url-regexp 0 t gnus-button-url 0) | 2533 ("^[^:]+:" ,gnus-button-url-regexp 0 t gnus-button-url 0) |
2539 ("^[^:]+:" "\\(<\\(url: \\)?news:\\([^>\n ]*\\)>\\)" 1 t | 2534 ("^[^:]+:" "\\(<\\(url: \\)?news:\\([^>\n ]*\\)>\\)" 1 t |
2540 gnus-button-message-id 3)) | 2535 gnus-button-message-id 3)) |
2548 HEADER is a regexp to match a header. For a fuller explanation, see | 2543 HEADER is a regexp to match a header. For a fuller explanation, see |
2549 `gnus-button-alist'." | 2544 `gnus-button-alist'." |
2550 :group 'gnus-article-buttons | 2545 :group 'gnus-article-buttons |
2551 :group 'gnus-article-headers | 2546 :group 'gnus-article-headers |
2552 :type '(repeat (list (regexp :tag "Header") | 2547 :type '(repeat (list (regexp :tag "Header") |
2553 regexp | 2548 regexp |
2554 (integer :tag "Button") | 2549 (integer :tag "Button") |
2555 (sexp :tag "Form") | 2550 (sexp :tag "Form") |
2556 (function :tag "Callback") | 2551 (function :tag "Callback") |
2557 (repeat :tag "Par" | 2552 (repeat :tag "Par" |
2558 :inline t | 2553 :inline t |
2624 n)) | 2619 n)) |
2625 | 2620 |
2626 (defun gnus-article-highlight (&optional force) | 2621 (defun gnus-article-highlight (&optional force) |
2627 "Highlight current article. | 2622 "Highlight current article. |
2628 This function calls `gnus-article-highlight-headers', | 2623 This function calls `gnus-article-highlight-headers', |
2629 `gnus-article-highlight-citation', | 2624 `gnus-article-highlight-citation', |
2630 `gnus-article-highlight-signature', and `gnus-article-add-buttons' to | 2625 `gnus-article-highlight-signature', and `gnus-article-add-buttons' to |
2631 do the highlighting. See the documentation for those functions." | 2626 do the highlighting. See the documentation for those functions." |
2632 (interactive (list 'force)) | 2627 (interactive (list 'force)) |
2633 (gnus-article-highlight-headers) | 2628 (gnus-article-highlight-headers) |
2634 (gnus-article-highlight-citation force) | 2629 (gnus-article-highlight-citation force) |
2655 (let ((alist gnus-header-face-alist) | 2650 (let ((alist gnus-header-face-alist) |
2656 (buffer-read-only nil) | 2651 (buffer-read-only nil) |
2657 (case-fold-search t) | 2652 (case-fold-search t) |
2658 (inhibit-point-motion-hooks t) | 2653 (inhibit-point-motion-hooks t) |
2659 entry regexp header-face field-face from hpoints fpoints) | 2654 entry regexp header-face field-face from hpoints fpoints) |
2660 (goto-char (point-min)) | 2655 (message-narrow-to-head) |
2661 (when (search-forward "\n\n" nil t) | 2656 (while (setq entry (pop alist)) |
2662 (narrow-to-region (1- (point)) (point-min)) | 2657 (goto-char (point-min)) |
2663 (while (setq entry (pop alist)) | 2658 (setq regexp (concat "^\\(" |
2664 (goto-char (point-min)) | 2659 (if (string-equal "" (nth 0 entry)) |
2665 (setq regexp (concat "^\\(" | 2660 "[^\t ]" |
2666 (if (string-equal "" (nth 0 entry)) | 2661 (nth 0 entry)) |
2667 "[^\t ]" | 2662 "\\)") |
2668 (nth 0 entry)) | 2663 header-face (nth 1 entry) |
2669 "\\)") | 2664 field-face (nth 2 entry)) |
2670 header-face (nth 1 entry) | 2665 (while (and (re-search-forward regexp nil t) |
2671 field-face (nth 2 entry)) | 2666 (not (eobp))) |
2672 (while (and (re-search-forward regexp nil t) | 2667 (beginning-of-line) |
2673 (not (eobp))) | 2668 (setq from (point)) |
2674 (beginning-of-line) | 2669 (unless (search-forward ":" nil t) |
2675 (setq from (point)) | 2670 (forward-char 1)) |
2676 (unless (search-forward ":" nil t) | 2671 (when (and header-face |
2677 (forward-char 1)) | 2672 (not (memq (point) hpoints))) |
2678 (when (and header-face | 2673 (push (point) hpoints) |
2679 (not (memq (point) hpoints))) | 2674 (gnus-put-text-property from (point) 'face header-face)) |
2680 (push (point) hpoints) | 2675 (when (and field-face |
2681 (gnus-put-text-property from (point) 'face header-face)) | 2676 (not (memq (setq from (point)) fpoints))) |
2682 (when (and field-face | 2677 (push from fpoints) |
2683 (not (memq (setq from (point)) fpoints))) | 2678 (if (re-search-forward "^[^ \t]" nil t) |
2684 (push from fpoints) | 2679 (forward-char -2) |
2685 (if (re-search-forward "^[^ \t]" nil t) | 2680 (goto-char (point-max))) |
2686 (forward-char -2) | 2681 (gnus-put-text-property from (point) 'face field-face)))))))) |
2687 (goto-char (point-max))) | |
2688 (gnus-put-text-property from (point) 'face field-face))))))))) | |
2689 | 2682 |
2690 (defun gnus-article-highlight-signature () | 2683 (defun gnus-article-highlight-signature () |
2691 "Highlight the signature in an article. | 2684 "Highlight the signature in an article. |
2692 It does this by highlighting everything after | 2685 It does this by highlighting everything after |
2693 `gnus-signature-separator' using `gnus-signature-face'." | 2686 `gnus-signature-separator' using `gnus-signature-face'." |
2694 (interactive) | 2687 (interactive) |
2695 (save-excursion | 2688 (save-excursion |
2696 (set-buffer gnus-article-buffer) | 2689 (set-buffer gnus-article-buffer) |
2697 (let ((buffer-read-only nil) | 2690 (let ((buffer-read-only nil) |
2698 (inhibit-point-motion-hooks t)) | 2691 (inhibit-point-motion-hooks t)) |
2717 \"External references\" are things like Message-IDs and URLs, as | 2710 \"External references\" are things like Message-IDs and URLs, as |
2718 specified by `gnus-button-alist'." | 2711 specified by `gnus-button-alist'." |
2719 (interactive (list 'force)) | 2712 (interactive (list 'force)) |
2720 (save-excursion | 2713 (save-excursion |
2721 (set-buffer gnus-article-buffer) | 2714 (set-buffer gnus-article-buffer) |
2722 ;; Remove all old markers. | |
2723 (let (marker entry) | |
2724 (while (setq marker (pop gnus-button-marker-list)) | |
2725 (goto-char marker) | |
2726 (when (setq entry (gnus-button-entry)) | |
2727 (put-text-property (match-beginning (nth 1 entry)) | |
2728 (match-end (nth 1 entry)) | |
2729 'gnus-callback nil)) | |
2730 (set-marker marker nil))) | |
2731 (let ((buffer-read-only nil) | 2715 (let ((buffer-read-only nil) |
2732 (inhibit-point-motion-hooks t) | 2716 (inhibit-point-motion-hooks t) |
2733 (case-fold-search t) | 2717 (case-fold-search t) |
2734 (alist gnus-button-alist) | 2718 (alist gnus-button-alist) |
2735 beg entry regexp) | 2719 beg entry regexp) |
2720 ;; Remove all old markers. | |
2721 (let (marker entry) | |
2722 (while (setq marker (pop gnus-button-marker-list)) | |
2723 (goto-char marker) | |
2724 (when (setq entry (gnus-button-entry)) | |
2725 (put-text-property (match-beginning (nth 1 entry)) | |
2726 (match-end (nth 1 entry)) | |
2727 'gnus-callback nil)) | |
2728 (set-marker marker nil))) | |
2729 ;; We skip the headers. | |
2736 (goto-char (point-min)) | 2730 (goto-char (point-min)) |
2737 ;; We skip the headers. | |
2738 (unless (search-forward "\n\n" nil t) | 2731 (unless (search-forward "\n\n" nil t) |
2739 (goto-char (point-max))) | 2732 (goto-char (point-max))) |
2740 (setq beg (point)) | 2733 (setq beg (point)) |
2741 (while (setq entry (pop alist)) | 2734 (while (setq entry (pop alist)) |
2742 (setq regexp (car entry)) | 2735 (setq regexp (car entry)) |
2749 (eval (nth 1 entry))) | 2742 (eval (nth 1 entry))) |
2750 (not (gnus-button-in-region-p | 2743 (not (gnus-button-in-region-p |
2751 start end 'gnus-callback))) | 2744 start end 'gnus-callback))) |
2752 ;; That optional form returned non-nil, so we add the | 2745 ;; That optional form returned non-nil, so we add the |
2753 ;; button. | 2746 ;; button. |
2754 (gnus-article-add-button | 2747 (gnus-article-add-button |
2755 start end 'gnus-button-push | 2748 start end 'gnus-button-push |
2756 (car (push (set-marker (make-marker) from) | 2749 (car (push (set-marker (make-marker) from) |
2757 gnus-button-marker-list)))))))))) | 2750 gnus-button-marker-list)))))))))) |
2758 | 2751 |
2759 ;; Add buttons to the head of an article. | 2752 ;; Add buttons to the head of an article. |
2760 (defun gnus-article-add-buttons-to-head () | 2753 (defun gnus-article-add-buttons-to-head () |
2786 (start (match-beginning (nth 1 entry))) | 2779 (start (match-beginning (nth 1 entry))) |
2787 (end (match-end (nth 1 entry))) | 2780 (end (match-end (nth 1 entry))) |
2788 (form (nth 2 entry))) | 2781 (form (nth 2 entry))) |
2789 (goto-char (match-end 0)) | 2782 (goto-char (match-end 0)) |
2790 (when (eval form) | 2783 (when (eval form) |
2791 (gnus-article-add-button | 2784 (gnus-article-add-button |
2792 start end (nth 3 entry) | 2785 start end (nth 3 entry) |
2793 (buffer-substring (match-beginning (nth 4 entry)) | 2786 (buffer-substring (match-beginning (nth 4 entry)) |
2794 (match-end (nth 4 entry))))))) | 2787 (match-end (nth 4 entry))))))) |
2795 (goto-char end)))) | 2788 (goto-char end)))) |
2796 (widen))) | 2789 (widen))) |
2800 (defun gnus-article-add-button (from to fun &optional data) | 2793 (defun gnus-article-add-button (from to fun &optional data) |
2801 "Create a button between FROM and TO with callback FUN and data DATA." | 2794 "Create a button between FROM and TO with callback FUN and data DATA." |
2802 (when gnus-article-button-face | 2795 (when gnus-article-button-face |
2803 (gnus-overlay-put (gnus-make-overlay from to) | 2796 (gnus-overlay-put (gnus-make-overlay from to) |
2804 'face gnus-article-button-face)) | 2797 'face gnus-article-button-face)) |
2805 (gnus-add-text-properties | 2798 (gnus-add-text-properties |
2806 from to | 2799 from to |
2807 (nconc (and gnus-article-mouse-face | 2800 (nconc (and gnus-article-mouse-face |
2808 (list gnus-mouse-face-prop gnus-article-mouse-face)) | 2801 (list gnus-mouse-face-prop gnus-article-mouse-face)) |
2809 (list 'gnus-callback fun) | 2802 (list 'gnus-callback fun) |
2810 (and data (list 'gnus-data data))))) | 2803 (and data (list 'gnus-data data))))) |
2882 (let (parts (start 0)) | 2875 (let (parts (start 0)) |
2883 (while (string-match pattern string start) | 2876 (while (string-match pattern string start) |
2884 (setq parts (cons (substring string start (match-beginning 0)) parts) | 2877 (setq parts (cons (substring string start (match-beginning 0)) parts) |
2885 start (match-end 0))) | 2878 start (match-end 0))) |
2886 (nreverse (cons (substring string start) parts)))) | 2879 (nreverse (cons (substring string start) parts)))) |
2887 | 2880 |
2888 (defun gnus-url-parse-query-string (query &optional downcase) | 2881 (defun gnus-url-parse-query-string (query &optional downcase) |
2889 (let (retval pairs cur key val) | 2882 (let (retval pairs cur key val) |
2890 (setq pairs (gnus-split-string query "&")) | 2883 (setq pairs (gnus-split-string query "&")) |
2891 (while pairs | 2884 (while pairs |
2892 (setq cur (car pairs) | 2885 (setq cur (car pairs) |
2900 (setq cur (assoc key retval)) | 2893 (setq cur (assoc key retval)) |
2901 (if cur | 2894 (if cur |
2902 (setcdr cur (cons val (cdr cur))) | 2895 (setcdr cur (cons val (cdr cur))) |
2903 (setq retval (cons (list key val) retval))))) | 2896 (setq retval (cons (list key val) retval))))) |
2904 retval)) | 2897 retval)) |
2905 | 2898 |
2906 (defun gnus-url-unhex (x) | 2899 (defun gnus-url-unhex (x) |
2907 (if (> x ?9) | 2900 (if (> x ?9) |
2908 (if (>= x ?a) | 2901 (if (>= x ?a) |
2909 (+ 10 (- x ?a)) | 2902 (+ 10 (- x ?a)) |
2910 (+ 10 (- x ?A))) | 2903 (+ 10 (- x ?A))) |
2911 (- x ?0))) | 2904 (- x ?0))) |
2912 | 2905 |
2913 (defun gnus-url-unhex-string (str &optional allow-newlines) | 2906 (defun gnus-url-unhex-string (str &optional allow-newlines) |
2914 "Remove %XXX embedded spaces, etc in a url. | 2907 "Remove %XXX embedded spaces, etc in a url. |
2915 If optional second argument ALLOW-NEWLINES is non-nil, then allow the | 2908 If optional second argument ALLOW-NEWLINES is non-nil, then allow the |
2916 decoding of carriage returns and line feeds in the string, which is normally | 2909 decoding of carriage returns and line feeds in the string, which is normally |
2917 forbidden in URL encoding." | 2910 forbidden in URL encoding." |
2921 (while (string-match "%[0-9a-f][0-9a-f]" str) | 2914 (while (string-match "%[0-9a-f][0-9a-f]" str) |
2922 (let* ((start (match-beginning 0)) | 2915 (let* ((start (match-beginning 0)) |
2923 (ch1 (gnus-url-unhex (elt str (+ start 1)))) | 2916 (ch1 (gnus-url-unhex (elt str (+ start 1)))) |
2924 (code (+ (* 16 ch1) | 2917 (code (+ (* 16 ch1) |
2925 (gnus-url-unhex (elt str (+ start 2)))))) | 2918 (gnus-url-unhex (elt str (+ start 2)))))) |
2926 (setq tmp (concat | 2919 (setq tmp (concat |
2927 tmp (substring str 0 start) | 2920 tmp (substring str 0 start) |
2928 (cond | 2921 (cond |
2929 (allow-newlines | 2922 (allow-newlines |
2930 (char-to-string code)) | 2923 (char-to-string code)) |
2931 ((or (= code ?\n) (= code ?\r)) | 2924 ((or (= code ?\n) (= code ?\r)) |
2932 " ") | 2925 " ") |
2933 (t (char-to-string code)))) | 2926 (t (char-to-string code)))) |
2934 str (substring str (match-end 0))))) | 2927 str (substring str (match-end 0))))) |
2935 (setq tmp (concat tmp str)) | 2928 (setq tmp (concat tmp str)) |
2936 tmp)) | 2929 tmp)) |
2937 | 2930 |
2938 (defun gnus-url-mailto (url) | 2931 (defun gnus-url-mailto (url) |
2939 ;; Send mail to someone | 2932 ;; Send mail to someone |
2940 (when (string-match "mailto:/*\\(.*\\)" url) | 2933 (when (string-match "mailto:/*\\(.*\\)" url) |
2941 (setq url (substring url (match-beginning 1) nil))) | 2934 (setq url (substring url (match-beginning 1) nil))) |
2942 (let (to args source-url subject func) | 2935 (let (to args source-url subject func) |
2987 (define-key gnus-prev-page-map gnus-mouse-2 'gnus-button-prev-page) | 2980 (define-key gnus-prev-page-map gnus-mouse-2 'gnus-button-prev-page) |
2988 (define-key gnus-prev-page-map "\r" 'gnus-button-prev-page)) | 2981 (define-key gnus-prev-page-map "\r" 'gnus-button-prev-page)) |
2989 | 2982 |
2990 (defun gnus-insert-prev-page-button () | 2983 (defun gnus-insert-prev-page-button () |
2991 (let ((buffer-read-only nil)) | 2984 (let ((buffer-read-only nil)) |
2992 (gnus-eval-format | 2985 (gnus-eval-format |
2993 gnus-prev-page-line-format nil | 2986 gnus-prev-page-line-format nil |
2994 `(gnus-prev t local-map ,gnus-prev-page-map | 2987 `(gnus-prev t local-map ,gnus-prev-page-map |
2995 gnus-callback gnus-article-button-prev-page)))) | 2988 gnus-callback gnus-article-button-prev-page)))) |
2996 | 2989 |
2997 (defvar gnus-next-page-map nil) | 2990 (defvar gnus-next-page-map nil) |
3019 | 3012 |
3020 (defun gnus-insert-next-page-button () | 3013 (defun gnus-insert-next-page-button () |
3021 (let ((buffer-read-only nil)) | 3014 (let ((buffer-read-only nil)) |
3022 (gnus-eval-format gnus-next-page-line-format nil | 3015 (gnus-eval-format gnus-next-page-line-format nil |
3023 `(gnus-next t local-map ,gnus-next-page-map | 3016 `(gnus-next t local-map ,gnus-next-page-map |
3024 gnus-callback | 3017 gnus-callback |
3025 gnus-article-button-next-page)))) | 3018 gnus-article-button-next-page)))) |
3026 | 3019 |
3027 (defun gnus-article-button-next-page (arg) | 3020 (defun gnus-article-button-next-page (arg) |
3028 "Go to the next page." | 3021 "Go to the next page." |
3029 (interactive "P") | 3022 (interactive "P") |
3036 "Go to the prev page." | 3029 "Go to the prev page." |
3037 (interactive "P") | 3030 (interactive "P") |
3038 (let ((win (selected-window))) | 3031 (let ((win (selected-window))) |
3039 (select-window (get-buffer-window gnus-article-buffer t)) | 3032 (select-window (get-buffer-window gnus-article-buffer t)) |
3040 (gnus-article-prev-page) | 3033 (gnus-article-prev-page) |
3041 (select-window win))) | 3034 (select-window win))) |
3042 | 3035 |
3043 (gnus-ems-redefine) | 3036 (gnus-ems-redefine) |
3044 | 3037 |
3045 (provide 'gnus-art) | 3038 (provide 'gnus-art) |
3046 | 3039 |