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