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