comparison lisp/gnus/shr.el @ 111830:79219ca01c7b

Merge changes made in Gnus trunk. nnir.el (nnir-categorize): Replace mapcar with mapc. shr.el (shr-urlify): Display the title in <a> tags. shr.el (shr-urlify): Show the URL before the title to avoid misleading URLs. gnus-sum.el (gnus-summary-show-article): Reverse the meanings of `C-u C-u g' and `C-u g' so that `C-u g' does what it traditionally did. gnus.texi (Paging the Article): Note the reverse meanings of `C-u C-u g'. gnus-html.el (gnus-html-put-image): Use widget instead of local maps so that TAB works. nnir.el (nnir-run-gmane): Use more careful test for gmane nntp server. nnimap.el (nnimap-process-expiry-targets): Avoid downloading articles unless necessary. gnus-util.el (gnus-output-to-mail): Require nnmail before using nnmail variables. shr.el (shr-stylesheet): New dynamic variable for cascading the styles. (shr-colorize-region): New function. (shr-insert-background-overlay): Remove. (shr-render-td): Background setting should be taken care of on a higher level. (shr-tag-body): Use post-hoc colorizations. (shr-descend): Only render color/background when they change. (shr-tag-body): Set up a style sheet based on bgcolor/fgcolor. (shr-put-color-1): Don't overwrite old colors. (shr-colorize-region): When the background color isn't explicit, use a fixed background. gnus.el (gnus-valid-select-methods): Allow nnimap to respool. nntp.el (nntp-snarf-error-message): nnheader-report takes a format string as the parameter. gnus-sum.el (gnus-summary-respool-article): The completion function expects a list instead of an alist.
author Katsumi Yamaoka <yamaoka@jpl.org>
date Sun, 05 Dec 2010 22:17:34 +0000
parents f97704487fb3
children 7e8cf0f45075
comparison
equal deleted inserted replaced
111829:a60f0af8cb39 111830:79219ca01c7b
92 (defvar shr-inhibit-images nil) 92 (defvar shr-inhibit-images nil)
93 (defvar shr-list-mode nil) 93 (defvar shr-list-mode nil)
94 (defvar shr-content-cache nil) 94 (defvar shr-content-cache nil)
95 (defvar shr-kinsoku-shorten nil) 95 (defvar shr-kinsoku-shorten nil)
96 (defvar shr-table-depth 0) 96 (defvar shr-table-depth 0)
97 (defvar shr-stylesheet nil)
97 98
98 (defvar shr-map 99 (defvar shr-map
99 (let ((map (make-sparse-keymap))) 100 (let ((map (make-sparse-keymap)))
100 (define-key map "a" 'shr-show-alt-text) 101 (define-key map "a" 'shr-show-alt-text)
101 (define-key map "i" 'shr-browse-image) 102 (define-key map "i" 'shr-browse-image)
189 (nreverse result))) 190 (nreverse result)))
190 191
191 (defun shr-descend (dom) 192 (defun shr-descend (dom)
192 (let ((function (intern (concat "shr-tag-" (symbol-name (car dom))) obarray)) 193 (let ((function (intern (concat "shr-tag-" (symbol-name (car dom))) obarray))
193 (style (cdr (assq :style (cdr dom)))) 194 (style (cdr (assq :style (cdr dom))))
195 (shr-stylesheet shr-stylesheet)
194 (start (point))) 196 (start (point)))
195 (when (and style 197 (when (and style
196 (string-match "color" style)) 198 (string-match "color" style))
197 (setq style (shr-parse-style style))) 199 (setq shr-stylesheet (nconc (shr-parse-style style)
200 shr-stylesheet)))
198 (if (fboundp function) 201 (if (fboundp function)
199 (funcall function (cdr dom)) 202 (funcall function (cdr dom))
200 (shr-generic (cdr dom))) 203 (shr-generic (cdr dom)))
201 (when (consp style) 204 (let ((color (cdr (assq 'color shr-stylesheet)))
202 (shr-insert-background-overlay (cdr (assq 'background-color style)) 205 (background (cdr (assq 'background-color
203 start) 206 shr-stylesheet))))
204 (shr-insert-foreground-overlay (cdr (assq 'color style)) 207 (when (and shr-stylesheet
205 start (point))))) 208 (or color background))
209 (shr-colorize-region start (point) color background)))))
206 210
207 (defun shr-generic (cont) 211 (defun shr-generic (cont)
208 (dolist (sub cont) 212 (dolist (sub cont)
209 (cond 213 (cond
210 ((eq (car sub) 'text) 214 ((eq (car sub) 'text)
542 (apply #'shr-fontize-cont cont types) 546 (apply #'shr-fontize-cont cont types)
543 (shr-ensure-paragraph)) 547 (shr-ensure-paragraph))
544 548
545 (autoload 'widget-convert-button "wid-edit") 549 (autoload 'widget-convert-button "wid-edit")
546 550
547 (defun shr-urlify (start url) 551 (defun shr-urlify (start url &optional title)
548 (widget-convert-button 552 (widget-convert-button
549 'url-link start (point) 553 'url-link start (point)
550 :help-echo url 554 :help-echo (if title (format "%s (%s)" url title) url)
551 :keymap shr-map 555 :keymap shr-map
552 url) 556 url)
553 (put-text-property start (point) 'shr-url url)) 557 (put-text-property start (point) 'shr-url url))
554 558
555 (defun shr-encode-url (url) 559 (defun shr-encode-url (url)
579 ;; Invert args and results and return only the new bg 583 ;; Invert args and results and return only the new bg
580 (list (cadr (shr-color-visible fg bg t)) nil)) 584 (list (cadr (shr-color-visible fg bg t)) nil))
581 (t 585 (t
582 (shr-color-visible bg fg))))))) 586 (shr-color-visible bg fg)))))))
583 587
584 (defun shr-get-background (pos) 588 (defun shr-colorize-region (start end fg &optional bg)
585 "Return background color at POS."
586 (dolist (overlay (overlays-in pos (1+ pos)))
587 (let ((background (plist-get (overlay-get overlay 'face)
588 :background)))
589 (when background
590 (return background)))))
591
592 (defun shr-insert-foreground-overlay (fg start end)
593 (when fg 589 (when fg
594 (let ((bg (shr-get-background start))) 590 (let ((new-colors (shr-color-check fg bg)))
595 (let ((new-colors (shr-color-check fg bg)))
596 (when new-colors
597 (overlay-put (make-overlay start end) 'face
598 (list :foreground (cadr new-colors))))))))
599
600 (defun shr-insert-background-overlay (bg start)
601 "Insert an overlay with background color BG at START.
602 The overlay has rear-advance set to t, so it will be used when
603 text will be inserted at start."
604 (when bg
605 (let ((new-colors (shr-color-check nil bg)))
606 (when new-colors 591 (when new-colors
607 (overlay-put (make-overlay start start nil nil t) 'face 592 (shr-put-color start end :foreground (cadr new-colors))
608 (list :background (car new-colors))))))) 593 (when bg
594 (shr-put-color start end :background (car new-colors)))))))
595
596 ;; Put a color in the region, but avoid putting colors on on blank
597 ;; text at the start of the line, and the newline at the end, to avoid
598 ;; ugliness. Also, don't overwrite any existing color information,
599 ;; since this can be called recursively, and we want the "inner" color
600 ;; to win.
601 (defun shr-put-color (start end type color)
602 (save-excursion
603 (goto-char start)
604 (while (< (point) end)
605 (when (bolp)
606 (skip-chars-forward " "))
607 (when (> (line-end-position) (point))
608 (shr-put-color-1 (point) (min (line-end-position) end) type color))
609 (if (< (line-end-position) end)
610 (forward-line 1)
611 (goto-char end)))))
612
613 (defun shr-put-color-1 (start end type color)
614 (let* ((old-props (get-text-property start 'face))
615 (do-put (not (memq type old-props)))
616 change)
617 (while (< start end)
618 (setq change (next-single-property-change start 'face nil end))
619 (when do-put
620 (put-text-property start change 'face
621 (nconc (list type color) old-props)))
622 (setq old-props (get-text-property change 'face))
623 (setq do-put (not (memq type old-props)))
624 (setq start change))
625 (when (and do-put
626 (> end start))
627 (put-text-property start end 'face
628 (nconc (list type color old-props))))))
609 629
610 ;;; Tag-specific rendering rules. 630 ;;; Tag-specific rendering rules.
611 631
612 (defun shr-tag-body (cont) 632 (defun shr-tag-body (cont)
613 (let ((start (point)) 633 (let* ((start (point))
614 (fgcolor (cdr (assq :fgcolor cont))) 634 (fgcolor (cdr (assq :fgcolor cont)))
615 (bgcolor (cdr (assq :bgcolor cont)))) 635 (bgcolor (cdr (assq :bgcolor cont)))
616 (shr-insert-background-overlay bgcolor start) 636 (shr-stylesheet (list (cons :color fgcolor)
637 (cons :background-color bgcolor))))
617 (shr-generic cont) 638 (shr-generic cont)
618 (shr-insert-foreground-overlay fgcolor start (point)))) 639 (shr-colorize-region start (point) fgcolor bgcolor)))
619 640
620 (defun shr-tag-p (cont) 641 (defun shr-tag-p (cont)
621 (shr-ensure-paragraph) 642 (shr-ensure-paragraph)
622 (shr-indent) 643 (shr-indent)
623 (shr-generic cont) 644 (shr-generic cont)
667 plist))))) 688 plist)))))
668 plist))) 689 plist)))
669 690
670 (defun shr-tag-a (cont) 691 (defun shr-tag-a (cont)
671 (let ((url (cdr (assq :href cont))) 692 (let ((url (cdr (assq :href cont)))
693 (title (cdr (assq :title cont)))
672 (start (point)) 694 (start (point))
673 shr-start) 695 shr-start)
674 (shr-generic cont) 696 (shr-generic cont)
675 (shr-urlify (or shr-start start) url))) 697 (shr-urlify (or shr-start start) url title)))
676 698
677 (defun shr-tag-object (cont) 699 (defun shr-tag-object (cont)
678 (let ((start (point)) 700 (let ((start (point))
679 url) 701 url)
680 (dolist (elem cont) 702 (dolist (elem cont)
816 838
817 (defun shr-tag-font (cont) 839 (defun shr-tag-font (cont)
818 (let ((start (point)) 840 (let ((start (point))
819 (color (cdr (assq :color cont)))) 841 (color (cdr (assq :color cont))))
820 (shr-generic cont) 842 (shr-generic cont)
821 (shr-insert-foreground-overlay color start (point)))) 843 (shr-colorize-region start (point) color)))
822 844
823 ;;; Table rendering algorithm. 845 ;;; Table rendering algorithm.
824 846
825 ;; Table rendering is the only complicated thing here. We do this by 847 ;; Table rendering is the only complicated thing here. We do this by
826 ;; first counting how many TDs there are in each TR, and registering 848 ;; first counting how many TDs there are in each TR, and registering
868 (footer (cdr (assq 'tfoot cont))) 890 (footer (cdr (assq 'tfoot cont)))
869 (bgcolor (cdr (assq :bgcolor cont))) 891 (bgcolor (cdr (assq :bgcolor cont)))
870 (nheader (if header (shr-max-columns header))) 892 (nheader (if header (shr-max-columns header)))
871 (nbody (if body (shr-max-columns body))) 893 (nbody (if body (shr-max-columns body)))
872 (nfooter (if footer (shr-max-columns footer)))) 894 (nfooter (if footer (shr-max-columns footer))))
873 (shr-insert-background-overlay bgcolor (point))
874 (shr-tag-table-1 895 (shr-tag-table-1
875 (nconc 896 (nconc
876 (if caption `((tr (td ,@caption)))) 897 (if caption `((tr (td ,@caption))))
877 (if header 898 (if header
878 (if footer 899 (if footer
1011 (setq i (1+ i)))) 1032 (setq i (1+ i))))
1012 (push (nreverse tds) trs)))) 1033 (push (nreverse tds) trs))))
1013 (nreverse trs))) 1034 (nreverse trs)))
1014 1035
1015 (defun shr-render-td (cont width fill) 1036 (defun shr-render-td (cont width fill)
1016 (let ((background (shr-get-background (point)))) 1037 (with-temp-buffer
1017 (with-temp-buffer 1038 (let ((cache (cdr (assoc (cons width cont) shr-content-cache))))
1018 (let ((cache (cdr (assoc (cons width cont) shr-content-cache)))) 1039 (if cache
1019 (if cache 1040 (insert cache)
1020 (insert cache) 1041 (let ((shr-width width)
1021 (shr-insert-background-overlay (or (cdr (assq :bgcolor cont)) 1042 (shr-indentation 0))
1022 background) 1043 (shr-generic cont))
1023 (point)) 1044 (delete-region
1024 (let ((shr-width width) 1045 (point)
1025 (shr-indentation 0)) 1046 (+ (point)
1026 (shr-generic cont)) 1047 (skip-chars-backward " \t\n")))
1027 (delete-region 1048 (push (cons (cons width cont) (buffer-string))
1028 (point) 1049 shr-content-cache)))
1029 (+ (point) 1050 (goto-char (point-min))
1030 (skip-chars-backward " \t\n"))) 1051 (let ((max 0))
1031 (push (cons (cons width cont) (buffer-string)) 1052 (while (not (eobp))
1032 shr-content-cache))) 1053 (end-of-line)
1033 (goto-char (point-min)) 1054 (setq max (max max (current-column)))
1034 (let ((max 0)) 1055 (forward-line 1))
1035 (while (not (eobp)) 1056 (when fill
1036 (end-of-line) 1057 (goto-char (point-min))
1037 (setq max (max max (current-column))) 1058 ;; If the buffer is totally empty, then put a single blank
1038 (forward-line 1)) 1059 ;; line here.
1039 (when fill 1060 (if (zerop (buffer-size))
1040 (goto-char (point-min)) 1061 (insert (make-string width ? ))
1041 ;; If the buffer is totally empty, then put a single blank 1062 ;; Otherwise, fill the buffer.
1042 ;; line here. 1063 (while (not (eobp))
1043 (if (zerop (buffer-size)) 1064 (end-of-line)
1044 (insert (make-string width ? )) 1065 (when (> (- width (current-column)) 0)
1045 ;; Otherwise, fill the buffer. 1066 (insert (make-string (- width (current-column)) ? )))
1046 (while (not (eobp)) 1067 (forward-line 1))))
1047 (end-of-line) 1068 (if fill
1048 (when (> (- width (current-column)) 0) 1069 (list max
1049 (insert (make-string (- width (current-column)) ? ))) 1070 (count-lines (point-min) (point-max))
1050 (forward-line 1)))) 1071 (split-string (buffer-string) "\n")
1051 (if fill 1072 (shr-collect-overlays))
1052 (list max 1073 (list max
1053 (count-lines (point-min) (point-max)) 1074 (shr-natural-width))))))
1054 (split-string (buffer-string) "\n")
1055 (shr-collect-overlays))
1056 (list max
1057 (shr-natural-width)))))))
1058 1075
1059 (defun shr-natural-width () 1076 (defun shr-natural-width ()
1060 (goto-char (point-min)) 1077 (goto-char (point-min))
1061 (let ((current 0) 1078 (let ((current 0)
1062 (max 0)) 1079 (max 0))