comparison lisp/gnus/gnus-cite.el @ 30:ec9a17fef872 r19-15b98

Import from CVS: tag r19-15b98
author cvs
date Mon, 13 Aug 2007 08:52:29 +0200
parents 1917ad0d78d7
children 131b0175ea99
comparison
equal deleted inserted replaced
29:7976500f47f9 30:ec9a17fef872
66 Set it to nil to parse all articles." 66 Set it to nil to parse all articles."
67 :group 'gnus-cite 67 :group 'gnus-cite
68 :type '(choice (const :tag "all" nil) 68 :type '(choice (const :tag "all" nil)
69 integer)) 69 integer))
70 70
71 (defcustom gnus-cite-prefix-regexp 71 (defcustom gnus-cite-prefix-regexp
72 "^[]>|:}+ ]*[]>|:}+]\\(.*>\\)?\\|^.*>" 72 "^[]>|:}+ ]*[]>|:}+]\\(.*>\\)?\\|^.*>"
73 "Regexp matching the longest possible citation prefix on a line." 73 "Regexp matching the longest possible citation prefix on a line."
74 :group 'gnus-cite 74 :group 'gnus-cite
75 :type 'regexp) 75 :type 'regexp)
76 76
77 (defcustom gnus-cite-max-prefix 20 77 (defcustom gnus-cite-max-prefix 20
78 "Maximum possible length for a citation prefix." 78 "Maximum possible length for a citation prefix."
79 :group 'gnus-cite 79 :group 'gnus-cite
80 :type 'integer) 80 :type 'integer)
81 81
82 (defcustom gnus-supercite-regexp 82 (defcustom gnus-supercite-regexp
83 (concat "^\\(" gnus-cite-prefix-regexp "\\)? *" 83 (concat "^\\(" gnus-cite-prefix-regexp "\\)? *"
84 ">>>>> +\"\\([^\"\n]+\\)\" +==") 84 ">>>>> +\"\\([^\"\n]+\\)\" +==")
85 "Regexp matching normal Supercite attribution lines. 85 "Regexp matching normal Supercite attribution lines.
86 The first grouping must match prefixes added by other packages." 86 The first grouping must match prefixes added by other packages."
87 :group 'gnus-cite 87 :group 'gnus-cite
108 "Regexp matching the end of an attribution line. 108 "Regexp matching the end of an attribution line.
109 The text matching the first grouping will be used as a button." 109 The text matching the first grouping will be used as a button."
110 :group 'gnus-cite 110 :group 'gnus-cite
111 :type 'regexp) 111 :type 'regexp)
112 112
113 (defface gnus-cite-attribution-face '((t 113 (defface gnus-cite-attribution-face '((t
114 (:underline t))) 114 (:underline t)))
115 "Face used for attribution lines.") 115 "Face used for attribution lines.")
116 116
117 (defcustom gnus-cite-attribution-face 'gnus-cite-attribution-face 117 (defcustom gnus-cite-attribution-face 'gnus-cite-attribution-face
118 "Face used for attribution lines. 118 "Face used for attribution lines.
124 (background dark)) 124 (background dark))
125 (:foreground "light blue")) 125 (:foreground "light blue"))
126 (((class color) 126 (((class color)
127 (background light)) 127 (background light))
128 (:foreground "MidnightBlue")) 128 (:foreground "MidnightBlue"))
129 (t 129 (t
130 (:italic t))) 130 (:italic t)))
131 "Citation face.") 131 "Citation face.")
132 132
133 (defface gnus-cite-face-2 '((((class color) 133 (defface gnus-cite-face-2 '((((class color)
134 (background dark)) 134 (background dark))
135 (:foreground "light cyan")) 135 (:foreground "light cyan"))
136 (((class color) 136 (((class color)
137 (background light)) 137 (background light))
138 (:foreground "firebrick")) 138 (:foreground "firebrick"))
139 (t 139 (t
140 (:italic t))) 140 (:italic t)))
141 "Citation face.") 141 "Citation face.")
142 142
143 (defface gnus-cite-face-3 '((((class color) 143 (defface gnus-cite-face-3 '((((class color)
144 (background dark)) 144 (background dark))
145 (:foreground "light yellow")) 145 (:foreground "light yellow"))
146 (((class color) 146 (((class color)
147 (background light)) 147 (background light))
148 (:foreground "dark green")) 148 (:foreground "dark green"))
149 (t 149 (t
150 (:italic t))) 150 (:italic t)))
151 "Citation face.") 151 "Citation face.")
152 152
153 (defface gnus-cite-face-4 '((((class color) 153 (defface gnus-cite-face-4 '((((class color)
154 (background dark)) 154 (background dark))
155 (:foreground "light pink")) 155 (:foreground "light pink"))
156 (((class color) 156 (((class color)
157 (background light)) 157 (background light))
158 (:foreground "OrangeRed")) 158 (:foreground "OrangeRed"))
159 (t 159 (t
160 (:italic t))) 160 (:italic t)))
161 "Citation face.") 161 "Citation face.")
162 162
163 (defface gnus-cite-face-5 '((((class color) 163 (defface gnus-cite-face-5 '((((class color)
164 (background dark)) 164 (background dark))
165 (:foreground "pale green")) 165 (:foreground "pale green"))
166 (((class color) 166 (((class color)
167 (background light)) 167 (background light))
168 (:foreground "dark khaki")) 168 (:foreground "dark khaki"))
169 (t 169 (t
170 (:italic t))) 170 (:italic t)))
171 "Citation face.") 171 "Citation face.")
172 172
173 (defface gnus-cite-face-6 '((((class color) 173 (defface gnus-cite-face-6 '((((class color)
174 (background dark)) 174 (background dark))
175 (:foreground "beige")) 175 (:foreground "beige"))
176 (((class color) 176 (((class color)
177 (background light)) 177 (background light))
178 (:foreground "dark violet")) 178 (:foreground "dark violet"))
179 (t 179 (t
180 (:italic t))) 180 (:italic t)))
181 "Citation face.") 181 "Citation face.")
182 182
183 (defface gnus-cite-face-7 '((((class color) 183 (defface gnus-cite-face-7 '((((class color)
184 (background dark)) 184 (background dark))
185 (:foreground "orange")) 185 (:foreground "orange"))
186 (((class color) 186 (((class color)
187 (background light)) 187 (background light))
188 (:foreground "SteelBlue4")) 188 (:foreground "SteelBlue4"))
189 (t 189 (t
190 (:italic t))) 190 (:italic t)))
191 "Citation face.") 191 "Citation face.")
192 192
193 (defface gnus-cite-face-8 '((((class color) 193 (defface gnus-cite-face-8 '((((class color)
194 (background dark)) 194 (background dark))
195 (:foreground "magenta")) 195 (:foreground "magenta"))
196 (((class color) 196 (((class color)
197 (background light)) 197 (background light))
198 (:foreground "magenta")) 198 (:foreground "magenta"))
199 (t 199 (t
200 (:italic t))) 200 (:italic t)))
201 "Citation face.") 201 "Citation face.")
202 202
203 (defface gnus-cite-face-9 '((((class color) 203 (defface gnus-cite-face-9 '((((class color)
204 (background dark)) 204 (background dark))
205 (:foreground "violet")) 205 (:foreground "violet"))
206 (((class color) 206 (((class color)
207 (background light)) 207 (background light))
208 (:foreground "violet")) 208 (:foreground "violet"))
209 (t 209 (t
210 (:italic t))) 210 (:italic t)))
211 "Citation face.") 211 "Citation face.")
212 212
213 (defface gnus-cite-face-10 '((((class color) 213 (defface gnus-cite-face-10 '((((class color)
214 (background dark)) 214 (background dark))
215 (:foreground "medium purple")) 215 (:foreground "medium purple"))
216 (((class color) 216 (((class color)
217 (background light)) 217 (background light))
218 (:foreground "medium purple")) 218 (:foreground "medium purple"))
219 (t 219 (t
220 (:italic t))) 220 (:italic t)))
221 "Citation face.") 221 "Citation face.")
222 222
223 (defface gnus-cite-face-11 '((((class color) 223 (defface gnus-cite-face-11 '((((class color)
224 (background dark)) 224 (background dark))
225 (:foreground "turquoise")) 225 (:foreground "turquoise"))
226 (((class color) 226 (((class color)
227 (background light)) 227 (background light))
228 (:foreground "turquoise")) 228 (:foreground "turquoise"))
229 (t 229 (t
230 (:italic t))) 230 (:italic t)))
231 "Citation face.") 231 "Citation face.")
232 232
233 (defcustom gnus-cite-face-list 233 (defcustom gnus-cite-face-list
234 '(gnus-cite-face-1 gnus-cite-face-2 gnus-cite-face-3 gnus-cite-face-4 234 '(gnus-cite-face-1 gnus-cite-face-2 gnus-cite-face-3 gnus-cite-face-4
235 gnus-cite-face-5 gnus-cite-face-6 gnus-cite-face-7 gnus-cite-face-8 235 gnus-cite-face-5 gnus-cite-face-6 gnus-cite-face-7 gnus-cite-face-8
236 gnus-cite-face-9 gnus-cite-face-10 gnus-cite-face-11) 236 gnus-cite-face-9 gnus-cite-face-10 gnus-cite-face-11)
237 "List of faces used for highlighting citations. 237 "List of faces used for highlighting citations.
238 238
239 When there are citations from multiple articles in the same message, 239 When there are citations from multiple articles in the same message,
240 Gnus will try to give each citation from each article its own face. 240 Gnus will try to give each citation from each article its own face.
241 This should make it easier to see who wrote what." 241 This should make it easier to see who wrote what."
242 :group 'gnus-cite 242 :group 'gnus-cite
255 ;;; Internal Variables: 255 ;;; Internal Variables:
256 256
257 (defvar gnus-cite-article nil) 257 (defvar gnus-cite-article nil)
258 258
259 (defvar gnus-cite-prefix-alist nil) 259 (defvar gnus-cite-prefix-alist nil)
260 ;; Alist of citation prefixes. 260 ;; Alist of citation prefixes.
261 ;; The cdr is a list of lines with that prefix. 261 ;; The cdr is a list of lines with that prefix.
262 262
263 (defvar gnus-cite-attribution-alist nil) 263 (defvar gnus-cite-attribution-alist nil)
264 ;; Alist of attribution lines. 264 ;; Alist of attribution lines.
265 ;; The car is a line number. 265 ;; The car is a line number.
275 ;; WROTE: is the attribution line number 275 ;; WROTE: is the attribution line number
276 ;; IN: is the line number of the previous line if part of the same attribution, 276 ;; IN: is the line number of the previous line if part of the same attribution,
277 ;; PREFIX: Is the citation prefix of the attribution line(s), and 277 ;; PREFIX: Is the citation prefix of the attribution line(s), and
278 ;; TAG: Is a Supercite tag, if any. 278 ;; TAG: Is a Supercite tag, if any.
279 279
280 (defvar gnus-cited-text-button-line-format-alist 280 (defvar gnus-cited-text-button-line-format-alist
281 `((?b (marker-position beg) ?d) 281 `((?b (marker-position beg) ?d)
282 (?e (marker-position end) ?d) 282 (?e (marker-position end) ?d)
283 (?l (- end beg) ?d))) 283 (?l (- end beg) ?d)))
284 (defvar gnus-cited-text-button-line-format-spec nil) 284 (defvar gnus-cited-text-button-line-format-spec nil)
285 285
291 The faces are taken from `gnus-cite-face-list'. 291 The faces are taken from `gnus-cite-face-list'.
292 Attribution lines are highlighted with the same face as the 292 Attribution lines are highlighted with the same face as the
293 corresponding citation merged with `gnus-cite-attribution-face'. 293 corresponding citation merged with `gnus-cite-attribution-face'.
294 294
295 Text is considered cited if at least `gnus-cite-minimum-match-count' 295 Text is considered cited if at least `gnus-cite-minimum-match-count'
296 lines matches `gnus-cite-prefix-regexp' with the same prefix. 296 lines matches `gnus-cite-prefix-regexp' with the same prefix.
297 297
298 Lines matching `gnus-cite-attribution-suffix' and perhaps 298 Lines matching `gnus-cite-attribution-suffix' and perhaps
299 `gnus-cite-attribution-prefix' are considered attribution lines." 299 `gnus-cite-attribution-prefix' are considered attribution lines."
300 (interactive (list 'force)) 300 (interactive (list 'force))
301 (save-excursion 301 (save-excursion
330 prefix (cdr entry) 330 prefix (cdr entry)
331 skip (gnus-cite-find-prefix number) 331 skip (gnus-cite-find-prefix number)
332 face (cdr (assoc prefix face-alist))) 332 face (cdr (assoc prefix face-alist)))
333 ;; Add attribution button. 333 ;; Add attribution button.
334 (goto-line number) 334 (goto-line number)
335 (when (re-search-forward gnus-cite-attribution-suffix 335 (when (re-search-forward gnus-cite-attribution-suffix
336 (save-excursion (end-of-line 1) (point)) 336 (save-excursion (end-of-line 1) (point))
337 t) 337 t)
338 (gnus-article-add-button (match-beginning 1) (match-end 1) 338 (gnus-article-add-button (match-beginning 1) (match-end 1)
339 'gnus-cite-toggle prefix)) 339 'gnus-cite-toggle prefix))
340 ;; Highlight attribution line. 340 ;; Highlight attribution line.
443 "Toggle hiding of all cited text except attribution lines. 443 "Toggle hiding of all cited text except attribution lines.
444 See the documentation for `gnus-article-highlight-citation'. 444 See the documentation for `gnus-article-highlight-citation'.
445 If given a negative prefix, always show; if given a positive prefix, 445 If given a negative prefix, always show; if given a positive prefix,
446 always hide." 446 always hide."
447 (interactive (append (gnus-article-hidden-arg) (list 'force))) 447 (interactive (append (gnus-article-hidden-arg) (list 'force)))
448 (setq gnus-cited-text-button-line-format-spec 448 (setq gnus-cited-text-button-line-format-spec
449 (gnus-parse-format gnus-cited-text-button-line-format 449 (gnus-parse-format gnus-cited-text-button-line-format
450 gnus-cited-text-button-line-format-alist t)) 450 gnus-cited-text-button-line-format-alist t))
451 (save-excursion 451 (save-excursion
452 (set-buffer gnus-article-buffer) 452 (set-buffer gnus-article-buffer)
453 (cond 453 (cond
454 ((gnus-article-check-hidden-text 'cite arg) 454 ((gnus-article-check-hidden-text 'cite arg)
466 (while marks 466 (while marks
467 (setq beg nil 467 (setq beg nil
468 end nil) 468 end nil)
469 (while (and marks (string= (cdar marks) "")) 469 (while (and marks (string= (cdar marks) ""))
470 (setq marks (cdr marks))) 470 (setq marks (cdr marks)))
471 (when marks 471 (when marks
472 (setq beg (caar marks))) 472 (setq beg (caar marks)))
473 (while (and marks (not (string= (cdar marks) ""))) 473 (while (and marks (not (string= (cdar marks) "")))
474 (setq marks (cdr marks))) 474 (setq marks (cdr marks)))
475 (when marks 475 (when marks
476 (setq end (caar marks))) 476 (setq end (caar marks)))
546 (while total 546 (while total
547 (setq hiden (car total) 547 (setq hiden (car total)
548 total (cdr total)) 548 total (cdr total))
549 (goto-line hiden) 549 (goto-line hiden)
550 (unless (assq hiden gnus-cite-attribution-alist) 550 (unless (assq hiden gnus-cite-attribution-alist)
551 (gnus-add-text-properties 551 (gnus-add-text-properties
552 (point) (progn (forward-line 1) (point)) 552 (point) (progn (forward-line 1) (point))
553 (nconc (list 'article-type 'cite) 553 (nconc (list 'article-type 'cite)
554 gnus-hidden-properties)))))))))) 554 gnus-hidden-properties))))))))))
555 555
556 (defun gnus-article-hide-citation-in-followups () 556 (defun gnus-article-hide-citation-in-followups ()
587 (defun gnus-cite-parse-wrapper () 587 (defun gnus-cite-parse-wrapper ()
588 ;; Wrap chopped gnus-cite-parse 588 ;; Wrap chopped gnus-cite-parse
589 (goto-char (point-min)) 589 (goto-char (point-min))
590 (unless (search-forward "\n\n" nil t) 590 (unless (search-forward "\n\n" nil t)
591 (goto-char (point-max))) 591 (goto-char (point-max)))
592 (save-excursion 592 (save-excursion
593 (gnus-cite-parse-attributions)) 593 (gnus-cite-parse-attributions))
594 ;; Try to avoid check citation if there is no reason to believe 594 ;; Try to avoid check citation if there is no reason to believe
595 ;; that article has citations 595 ;; that article has citations
596 (if (or gnus-cite-always-check 596 (if (or gnus-cite-always-check
597 (save-excursion 597 (save-excursion
602 (save-excursion 602 (save-excursion
603 (gnus-cite-connect-attributions))))) 603 (gnus-cite-connect-attributions)))))
604 604
605 (defun gnus-cite-parse () 605 (defun gnus-cite-parse ()
606 ;; Parse and connect citation prefixes and attribution lines. 606 ;; Parse and connect citation prefixes and attribution lines.
607 607
608 ;; Parse current buffer searching for citation prefixes. 608 ;; Parse current buffer searching for citation prefixes.
609 (let ((line (1+ (count-lines (point-min) (point)))) 609 (let ((line (1+ (count-lines (point-min) (point))))
610 (case-fold-search t) 610 (case-fold-search t)
611 (max (save-excursion 611 (max (save-excursion
612 (goto-char (point-max)) 612 (goto-char (point-max))
632 ;; Each prefix. 632 ;; Each prefix.
633 (setq end (match-end 0) 633 (setq end (match-end 0)
634 prefix (buffer-substring begin end)) 634 prefix (buffer-substring begin end))
635 (gnus-set-text-properties 0 (length prefix) nil prefix) 635 (gnus-set-text-properties 0 (length prefix) nil prefix)
636 (setq entry (assoc prefix alist)) 636 (setq entry (assoc prefix alist))
637 (if entry 637 (if entry
638 (setcdr entry (cons line (cdr entry))) 638 (setcdr entry (cons line (cdr entry)))
639 (push (list prefix line) alist)) 639 (push (list prefix line) alist))
640 (goto-char begin)) 640 (goto-char begin))
641 (goto-char start) 641 (goto-char start)
642 (setq line (1+ line))) 642 (setq line (1+ line)))
657 ) 657 )
658 ((< (length numbers) gnus-cite-minimum-match-count) 658 ((< (length numbers) gnus-cite-minimum-match-count)
659 ;; Too few lines with this prefix. We keep it a bit 659 ;; Too few lines with this prefix. We keep it a bit
660 ;; longer in case it is an exact match for an attribution 660 ;; longer in case it is an exact match for an attribution
661 ;; line, but we don't remove the line from other 661 ;; line, but we don't remove the line from other
662 ;; prefixes. 662 ;; prefixes.
663 (push entry gnus-cite-prefix-alist)) 663 (push entry gnus-cite-prefix-alist))
664 (t 664 (t
665 (push entry 665 (push entry
666 gnus-cite-prefix-alist) 666 gnus-cite-prefix-alist)
667 ;; Remove articles from other prefixes. 667 ;; Remove articles from other prefixes.
668 (let ((loop alist) 668 (let ((loop alist)
669 current) 669 current)
670 (while loop 670 (while loop
671 (setq current (car loop) 671 (setq current (car loop)
672 loop (cdr loop)) 672 loop (cdr loop))
673 (setcdr current 673 (setcdr current
674 (gnus-set-difference (cdr current) numbers))))))))) 674 (gnus-set-difference (cdr current) numbers)))))))))
675 675
676 (defun gnus-cite-parse-attributions () 676 (defun gnus-cite-parse-attributions ()
677 (let (al-alist) 677 (let (al-alist)
678 ;; Parse attributions 678 ;; Parse attributions
704 (let ((al (buffer-substring (save-excursion (beginning-of-line 0) 704 (let ((al (buffer-substring (save-excursion (beginning-of-line 0)
705 (1+ (point))) 705 (1+ (point)))
706 end))) 706 end)))
707 (if (not (assoc al al-alist)) 707 (if (not (assoc al al-alist))
708 (progn 708 (progn
709 (push (list wrote in prefix tag) 709 (push (list wrote in prefix tag)
710 gnus-cite-loose-attribution-alist) 710 gnus-cite-loose-attribution-alist)
711 (push (cons al t) al-alist)))))))) 711 (push (cons al t) al-alist))))))))
712 712
713 (defun gnus-cite-connect-attributions () 713 (defun gnus-cite-connect-attributions ()
714 ;; Connect attributions to citations 714 ;; Connect attributions to citations
719 ;; Parse current buffer searching for attribution lines. 719 ;; Parse current buffer searching for attribution lines.
720 ;; Find exact supercite citations. 720 ;; Find exact supercite citations.
721 (gnus-cite-match-attributions 'small nil 721 (gnus-cite-match-attributions 'small nil
722 (lambda (prefix tag) 722 (lambda (prefix tag)
723 (when tag 723 (when tag
724 (concat "\\`" 724 (concat "\\`"
725 (regexp-quote prefix) "[ \t]*" 725 (regexp-quote prefix) "[ \t]*"
726 (regexp-quote tag) ">")))) 726 (regexp-quote tag) ">"))))
727 ;; Find loose supercite citations after attributions. 727 ;; Find loose supercite citations after attributions.
728 (gnus-cite-match-attributions 'small t 728 (gnus-cite-match-attributions 'small t
729 (lambda (prefix tag) 729 (lambda (prefix tag)
730 (when tag 730 (when tag
775 ;; will be considered. 775 ;; will be considered.
776 ;; 776 ;;
777 ;; If FUN is non-nil, it will be called with the arguments (WROTE 777 ;; If FUN is non-nil, it will be called with the arguments (WROTE
778 ;; PREFIX TAG) and expected to return a regular expression. Only 778 ;; PREFIX TAG) and expected to return a regular expression. Only
779 ;; citations whose prefix matches the regular expression will be 779 ;; citations whose prefix matches the regular expression will be
780 ;; considered. 780 ;; considered.
781 ;; 781 ;;
782 ;; WROTE is the attribution line number. 782 ;; WROTE is the attribution line number.
783 ;; PREFIX is the attribution line prefix. 783 ;; PREFIX is the attribution line prefix.
784 ;; TAG is the Supercite tag on the attribution line. 784 ;; TAG is the Supercite tag on the attribution line.
785 (let ((atts gnus-cite-loose-attribution-alist) 785 (let ((atts gnus-cite-loose-attribution-alist)
786 (case-fold-search t) 786 (case-fold-search t)
795 regexp (if fun (funcall fun prefix tag) "") 795 regexp (if fun (funcall fun prefix tag) "")
796 size (cond ((eq sort 'small) t) 796 size (cond ((eq sort 'small) t)
797 ((eq sort 'first) nil) 797 ((eq sort 'first) nil)
798 (t (< (length (gnus-cite-find-loose prefix)) 2))) 798 (t (< (length (gnus-cite-find-loose prefix)) 2)))
799 limit (if after wrote -1) 799 limit (if after wrote -1)
800 smallest 1000000 800 smallest 1000000
801 best nil) 801 best nil)
802 (let ((cites gnus-cite-loose-prefix-alist) 802 (let ((cites gnus-cite-loose-prefix-alist)
803 cite candidate numbers first compare) 803 cite candidate numbers first compare)
804 (while cites 804 (while cites
805 (setq cite (car cites) 805 (setq cite (car cites)
880 (cond ((get-text-property (point) 'invisible) 880 (cond ((get-text-property (point) 'invisible)
881 (remove-text-properties (point) (progn (forward-line 1) (point)) 881 (remove-text-properties (point) (progn (forward-line 1) (point))
882 gnus-hidden-properties)) 882 gnus-hidden-properties))
883 ((assq number gnus-cite-attribution-alist)) 883 ((assq number gnus-cite-attribution-alist))
884 (t 884 (t
885 (gnus-add-text-properties 885 (gnus-add-text-properties
886 (point) (progn (forward-line 1) (point)) 886 (point) (progn (forward-line 1) (point))
887 (nconc (list 'article-type 'cite) 887 (nconc (list 'article-type 'cite)
888 gnus-hidden-properties)))))))) 888 gnus-hidden-properties))))))))
889 889
890 (defun gnus-cite-find-prefix (line) 890 (defun gnus-cite-find-prefix (line)