aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGnus developers2010-10-03 00:33:27 +0000
committerKatsumi Yamaoka2010-10-03 00:33:27 +0000
commit870409d4fb06834c28e75cd653ad8aa2a7e8f581 (patch)
tree8068a94b7d19168f48eef4ea22c081ca1c031209
parent2a847524ab57b1b3d6eaa7e12b96be52dbb79509 (diff)
downloademacs-870409d4fb06834c28e75cd653ad8aa2a7e8f581.tar.gz
emacs-870409d4fb06834c28e75cd653ad8aa2a7e8f581.zip
Merge changes made in Gnus trunk.
shr.el: Start implementation. shr.el: Continue implementation. gnus-gravatar.el (gnus-gravatar-insert): Adjust character where we should go backward. shr.el: Minimally useful state achieved. mm-decode.el (mm-text-html-renderer): Switch to using shr.el for HTML rendering. shr.el: (shr-insert): Add a newline after every picture before text. gnus.texi (Splitting Mail): Really fix the @ref syntax. shr.el (shr-add-font): Use overlays for combining faces. shr.el (shr-add-font): Use overlays for combining faces. shr.el (shr-insert): Pass upwards the text start point. gnus-util.el: Reintroduce multiple completion functions.
-rw-r--r--doc/misc/ChangeLog1
-rw-r--r--doc/misc/gnus.texi2
-rw-r--r--lisp/gnus/ChangeLog25
-rw-r--r--lisp/gnus/gnus-gravatar.el2
-rw-r--r--lisp/gnus/gnus-html.el28
-rw-r--r--lisp/gnus/gnus-util.el63
-rw-r--r--lisp/gnus/mm-decode.el11
-rw-r--r--lisp/gnus/shr.el211
8 files changed, 317 insertions, 26 deletions
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog
index 299f29166ea..0b2c79088ac 100644
--- a/doc/misc/ChangeLog
+++ b/doc/misc/ChangeLog
@@ -1,6 +1,7 @@
12010-10-02 Lars Magne Ingebrigtsen <larsi@gnus.org> 12010-10-02 Lars Magne Ingebrigtsen <larsi@gnus.org>
2 2
3 * gnus.texi (Splitting Mail): Fix @xref syntax. 3 * gnus.texi (Splitting Mail): Fix @xref syntax.
4 (Splitting Mail): Really fix the @ref syntax.
4 5
52010-10-01 Lars Magne Ingebrigtsen <larsi@gnus.org> 62010-10-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
6 7
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 5431a57dc5a..00f58b2307a 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -15111,7 +15111,7 @@ message. The function should return a list of group names that it
15111thinks should carry this mail message. 15111thinks should carry this mail message.
15112 15112
15113This variable can also be a fancy split method. For the syntax, 15113This variable can also be a fancy split method. For the syntax,
15114@pxref{Fancy Mail Splitting}. 15114see @ref{Fancy Mail Splitting}.
15115 15115
15116Note that the mail back ends are free to maul the poor, innocent, 15116Note that the mail back ends are free to maul the poor, innocent,
15117incoming headers all they want to. They all add @code{Lines} headers; 15117incoming headers all they want to. They all add @code{Lines} headers;
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 64658bc629c..8d227906aca 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,28 @@
12010-10-02 Julien Danjou <julien@danjou.info>
2
3 * gnus-util.el (gnus-iswitchb-completing-read): New function.
4 (gnus-ido-completing-read): New function.
5 (gnus-emacs-completing-read): New function.
6 (gnus-completing-read): Use gnus-completing-read-function.
7 Add gnus-completing-read-function.
8
92010-10-02 Lars Magne Ingebrigtsen <larsi@gnus.org>
10
11 * shr.el (shr-insert-document): Autoload.
12 (shr-img): Be silent.
13 (shr-insert): Add a newline after every picture before text.
14 (shr-add-font): Use overlays for combining faces.
15 (shr-insert): Pass upwards the text start point.
16
17 * mm-decode.el (mm-text-html-renderer): Default to shr.el rendering, if
18 possible.
19 (mm-shr): New function.
20
212010-10-02 Julien Danjou <julien@danjou.info>
22
23 * gnus-gravatar.el (gnus-gravatar-insert): Adjust character where we
24 should go backward.
25
12010-10-02 Juanma Barranquero <lekktu@gmail.com> 262010-10-02 Juanma Barranquero <lekktu@gmail.com>
2 27
3 * shr.el (shr): Fix typo in provide call. 28 * shr.el (shr): Fix typo in provide call.
diff --git a/lisp/gnus/gnus-gravatar.el b/lisp/gnus/gnus-gravatar.el
index 2af975b09c7..de373cfdf05 100644
--- a/lisp/gnus/gnus-gravatar.el
+++ b/lisp/gnus/gnus-gravatar.el
@@ -76,7 +76,7 @@ Set image category to CATEGORY."
76 (search-backward mail-address nil t))) 76 (search-backward mail-address nil t)))
77 (goto-char (1- (point))) 77 (goto-char (1- (point)))
78 ;; If we're on the " quoting the name, go backward 78 ;; If we're on the " quoting the name, go backward
79 (when (looking-at "\"") 79 (when (looking-at "[\"<]")
80 (goto-char (1- (point)))) 80 (goto-char (1- (point))))
81 ;; Do not do anything if there's already a gravatar. This can 81 ;; Do not do anything if there's already a gravatar. This can
82 ;; happens if the buffer has been regenerated in the mean time, for 82 ;; happens if the buffer has been regenerated in the mean time, for
diff --git a/lisp/gnus/gnus-html.el b/lisp/gnus/gnus-html.el
index 0b64a237426..a6a243adc09 100644
--- a/lisp/gnus/gnus-html.el
+++ b/lisp/gnus/gnus-html.el
@@ -402,7 +402,8 @@ Return a string with image data."
402 402
403(defun gnus-html-put-image (data url &optional alt-text) 403(defun gnus-html-put-image (data url &optional alt-text)
404 (when (gnus-graphic-display-p) 404 (when (gnus-graphic-display-p)
405 (let* ((start (text-property-any (point-min) (point-max) 'gnus-image-url url)) 405 (let* ((start (text-property-any (point-min) (point-max)
406 'gnus-image-url url))
406 (end (when start 407 (end (when start
407 (next-single-property-change start 'gnus-image-url)))) 408 (next-single-property-change start 'gnus-image-url))))
408 ;; Image found? 409 ;; Image found?
@@ -416,7 +417,8 @@ Return a string with image data."
416 (image-size image t))))) 417 (image-size image t)))))
417 (save-excursion 418 (save-excursion
418 (goto-char start) 419 (goto-char start)
419 (let ((alt-text (or alt-text (buffer-substring-no-properties start end)))) 420 (let ((alt-text (or alt-text
421 (buffer-substring-no-properties start end))))
420 (if (and image 422 (if (and image
421 ;; Kludge to avoid displaying 30x30 gif images, which 423 ;; Kludge to avoid displaying 30x30 gif images, which
422 ;; seems to be a signal of a broken image. 424 ;; seems to be a signal of a broken image.
@@ -424,8 +426,9 @@ Return a string with image data."
424 (glyphp image) 426 (glyphp image)
425 (listp image)) 427 (listp image))
426 (eq (if (featurep 'xemacs) 428 (eq (if (featurep 'xemacs)
427 (let ((d (cdadar (specifier-spec-list 429 (let ((d (cdadar
428 (glyph-image image))))) 430 (specifier-spec-list
431 (glyph-image image)))))
429 (and (vectorp d) 432 (and (vectorp d)
430 (aref d 0))) 433 (aref d 0)))
431 (plist-get (cdr image) :type)) 434 (plist-get (cdr image) :type))
@@ -437,17 +440,21 @@ Return a string with image data."
437 (delete-region start end) 440 (delete-region start end)
438 (gnus-put-image image alt-text 'external) 441 (gnus-put-image image alt-text 'external)
439 (gnus-put-text-property start (point) 'help-echo alt-text) 442 (gnus-put-text-property start (point) 'help-echo alt-text)
440 (gnus-overlay-put (gnus-make-overlay start (point)) 'local-map 443 (gnus-overlay-put
441 gnus-html-displayed-image-map) 444 (gnus-make-overlay start (point)) 'local-map
442 (gnus-put-text-property start (point) 'gnus-alt-text alt-text) 445 gnus-html-displayed-image-map)
446 (gnus-put-text-property start (point)
447 'gnus-alt-text alt-text)
443 (when url 448 (when url
444 (gnus-put-text-property start (point) 'gnus-image-url url)) 449 (gnus-put-text-property start (point)
450 'gnus-image-url url))
445 (gnus-add-image 'external image) 451 (gnus-add-image 'external image)
446 t) 452 t)
447 ;; Bad image, try to show something else 453 ;; Bad image, try to show something else
448 (when (fboundp 'find-image) 454 (when (fboundp 'find-image)
449 (delete-region start end) 455 (delete-region start end)
450 (setq image (find-image '((:type xpm :file "lock-broken.xpm")))) 456 (setq image (find-image
457 '((:type xpm :file "lock-broken.xpm"))))
451 (gnus-put-image image alt-text 'internal) 458 (gnus-put-image image alt-text 'internal)
452 (gnus-add-image 'internal image)) 459 (gnus-add-image 'internal image))
453 nil)))))))) 460 nil))))))))
@@ -458,7 +465,8 @@ Return a string with image data."
458 image 465 image
459 (let* ((width (car size)) 466 (let* ((width (car size))
460 (height (cdr size)) 467 (height (cdr size))
461 (edges (gnus-window-inside-pixel-edges (get-buffer-window (current-buffer)))) 468 (edges (gnus-window-inside-pixel-edges
469 (get-buffer-window (current-buffer))))
462 (window-width (truncate (* gnus-max-image-proportion 470 (window-width (truncate (* gnus-max-image-proportion
463 (- (nth 2 edges) (nth 0 edges))))) 471 (- (nth 2 edges) (nth 0 edges)))))
464 (window-height (truncate (* gnus-max-image-proportion 472 (window-height (truncate (* gnus-max-image-proportion
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index d188ebab734..0bf5b66a71d 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -44,11 +44,19 @@
44 (defmacro with-no-warnings (&rest body) 44 (defmacro with-no-warnings (&rest body)
45 `(progn ,@body)))) 45 `(progn ,@body))))
46 46
47(defcustom gnus-use-ido nil 47(defcustom gnus-completing-read-function 'gnus-emacs-completing-read
48 "Whether to use `ido' for `completing-read'." 48 "Function use to do completing read."
49 :version "24.1" 49 :version "24.1"
50 :group 'gnus-meta 50 :group 'gnus-meta
51 :type 'boolean) 51 :type '(radio (function-item
52 :doc "Use Emacs standard `completing-read' function."
53 gnus-emacs-completing-read)
54 (function-item
55 :doc "Use `ido-completing-read' function."
56 gnus-ido-completing-read)
57 (function-item
58 :doc "Use iswitchb based completing-read function."
59 gnus-iswitchb-completing-read)))
52 60
53(defcustom gnus-completion-styles 61(defcustom gnus-completion-styles
54 (if (and (boundp 'completion-styles-alist) 62 (if (and (boundp 'completion-styles-alist)
@@ -1585,17 +1593,46 @@ SPEC is a predicate specifier that contains stuff like `or', `and',
1585 1593
1586(defun gnus-completing-read (prompt collection &optional require-match 1594(defun gnus-completing-read (prompt collection &optional require-match
1587 initial-input history def) 1595 initial-input history def)
1588 "Call `completing-read' or `ido-completing-read'. 1596 "Call `gnus-completing-read-function'."
1589Depends on `gnus-use-ido'." 1597 (funcall gnus-completing-read-function
1598 (concat prompt (when def
1599 (concat " (default " def ")"))
1600 ": ")
1601 collection require-match initial-input history def))
1602
1603(defun gnus-emacs-completing-read (prompt collection &optional require-match
1604 initial-input history def)
1605 "Call standard `completing-read-function'."
1590 (let ((completion-styles gnus-completion-styles)) 1606 (let ((completion-styles gnus-completion-styles))
1591 (funcall 1607 (completing-read prompt collection nil require-match initial-input history def)))
1592 (if gnus-use-ido 1608
1593 'ido-completing-read 1609(defun gnus-ido-completing-read (prompt collection &optional require-match
1594 'completing-read) 1610 initial-input history def)
1595 (concat prompt (when def 1611 "Call `ido-completing-read-function'."
1596 (concat " (default " def ")")) 1612 (require 'ido)
1597 ": ") 1613 (ido-completing-read prompt collection nil require-match initial-input history def))
1598 collection nil require-match initial-input history def))) 1614
1615(defun gnus-iswitchb-completing-read (prompt collection &optional require-match
1616 initial-input history def)
1617 "`iswitchb' based completing-read function."
1618 (require 'iswitchb)
1619 (let ((iswitchb-make-buflist-hook
1620 (lambda ()
1621 (setq iswitchb-temp-buflist
1622 (let ((choices (append
1623 (when initial-input (list initial-input))
1624 (symbol-value history) collection))
1625 filtered-choices)
1626 (dolist (x choices)
1627 (setq filtered-choices (adjoin x filtered-choices)))
1628 (nreverse filtered-choices))))))
1629 (unwind-protect
1630 (progn
1631 (when (not iswitchb-mode)
1632 (add-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup))
1633 (iswitchb-read-buffer prompt def require-match))
1634 (when (not iswitchb-mode)
1635 (remove-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup)))))
1599 1636
1600(defun gnus-graphic-display-p () 1637(defun gnus-graphic-display-p ()
1601 (if (featurep 'xemacs) 1638 (if (featurep 'xemacs)
diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el
index 7562e57ca8f..e98d66683c9 100644
--- a/lisp/gnus/mm-decode.el
+++ b/lisp/gnus/mm-decode.el
@@ -105,7 +105,8 @@
105 ,disposition ,description ,cache ,id)) 105 ,disposition ,description ,cache ,id))
106 106
107(defcustom mm-text-html-renderer 107(defcustom mm-text-html-renderer
108 (cond ((executable-find "w3m") 'gnus-article-html) 108 (cond ((fboundp 'libxml-parse-html-region) 'mm-shr)
109 ((executable-find "w3m") 'gnus-article-html)
109 ((executable-find "links") 'links) 110 ((executable-find "links") 'links)
110 ((executable-find "lynx") 'lynx) 111 ((executable-find "lynx") 'lynx)
111 ((locate-library "w3") 'w3) 112 ((locate-library "w3") 'w3)
@@ -1674,6 +1675,14 @@ If RECURSIVE, search recursively."
1674 (and (eq (mm-body-7-or-8) '7bit) 1675 (and (eq (mm-body-7-or-8) '7bit)
1675 (not (mm-long-lines-p 76)))))) 1676 (not (mm-long-lines-p 76))))))
1676 1677
1678(defun mm-shr (handle)
1679 (let ((article-buffer (current-buffer)))
1680 (unless handle
1681 (setq handle (mm-dissect-buffer t)))
1682 (shr-insert-document
1683 (mm-with-part handle
1684 (libxml-parse-html-region (point-min) (point-max))))))
1685
1677(provide 'mm-decode) 1686(provide 'mm-decode)
1678 1687
1679;;; mm-decode.el ends here 1688;;; mm-decode.el ends here
diff --git a/lisp/gnus/shr.el b/lisp/gnus/shr.el
index c5d34b90f36..4a778b892de 100644
--- a/lisp/gnus/shr.el
+++ b/lisp/gnus/shr.el
@@ -30,6 +30,217 @@
30 30
31;;; Code: 31;;; Code:
32 32
33(defgroup shr nil
34 "Simple HTML Renderer"
35 :group 'mail)
36
37(defcustom shr-max-image-proportion 0.9
38 "How big pictures displayed are in relation to the window they're in.
39A value of 0.7 means that they are allowed to take up 70% of the
40width and height of the window. If they are larger than this,
41and Emacs supports it, then the images will be rescaled down to
42fit these criteria."
43 :version "24.1"
44 :group 'shr
45 :type 'float)
46
47(defcustom shr-blocked-images nil
48 "Images that have URLs matching this regexp will be blocked."
49 :version "24.1"
50 :group 'shr
51 :type 'regexp)
52
53(defvar shr-folding-mode nil)
54(defvar shr-state nil)
55(defvar shr-start nil)
56
57(defvar shr-width 70)
58
59(defun shr-transform-dom (dom)
60 (let ((result (list (pop dom))))
61 (dolist (arg (pop dom))
62 (push (cons (intern (concat ":" (symbol-name (car arg))) obarray)
63 (cdr arg))
64 result))
65 (dolist (sub dom)
66 (if (stringp sub)
67 (push (cons :text sub) result)
68 (push (shr-transform-dom sub) result)))
69 (nreverse result)))
70
71;;;###autoload
72(defun shr-insert-document (dom)
73 (let ((shr-state nil)
74 (shr-start nil))
75 (shr-descend (shr-transform-dom dom))))
76
77(defun shr-descend (dom)
78 (let ((function (intern (concat "shr-" (symbol-name (car dom))) obarray)))
79 (if (fboundp function)
80 (funcall function (cdr dom))
81 (shr-generic (cdr dom)))))
82
83(defun shr-generic (cont)
84 (dolist (sub cont)
85 (cond
86 ((eq (car sub) :text)
87 (shr-insert (cdr sub)))
88 ((consp (cdr sub))
89 (shr-descend sub)))))
90
91(defun shr-p (cont)
92 (shr-ensure-newline)
93 (insert "\n")
94 (shr-generic cont)
95 (insert "\n"))
96
97(defun shr-b (cont)
98 (shr-fontize-cont cont 'bold))
99
100(defun shr-i (cont)
101 (shr-fontize-cont cont 'italic))
102
103(defun shr-u (cont)
104 (shr-fontize-cont cont 'underline))
105
106(defun shr-s (cont)
107 (shr-fontize-cont cont 'strikethru))
108
109(defun shr-fontize-cont (cont type)
110 (let (shr-start)
111 (shr-generic cont)
112 (shr-add-font shr-start (point) type)))
113
114(defun shr-add-font (start end type)
115 (let ((overlay (make-overlay start end)))
116 (overlay-put overlay 'face type)))
117
118(defun shr-a (cont)
119 (let ((url (cdr (assq :href cont)))
120 shr-start)
121 (shr-generic cont)
122 (widget-convert-button
123 'link shr-start (point)
124 :action 'shr-browse-url
125 :url url
126 :keymap widget-keymap
127 :help-echo url)))
128
129(defun shr-browse-url (widget &rest stuff)
130 (browse-url (widget-get widget :url)))
131
132(defun shr-img (cont)
133 (let ((start (point-marker)))
134 (let ((alt (cdr (assq :alt cont)))
135 (url (cdr (assq :src cont))))
136 (when (zerop (length alt))
137 (setq alt "[img]"))
138 (cond
139 ((and shr-blocked-images
140 (string-match shr-blocked-images url))
141 (insert alt))
142 ((url-is-cached (browse-url-url-encode-chars url "[&)$ ]"))
143 (shr-put-image (shr-get-image-data url) (point) alt))
144 (t
145 (insert alt)
146 (url-retrieve url 'shr-image-fetched
147 (list (current-buffer) start (point-marker))
148 t)))
149 (insert " ")
150 (setq shr-state 'image))))
151
152(defun shr-image-fetched (status buffer start end)
153 (when (and (buffer-name buffer)
154 (not (plist-get status :error)))
155 (url-store-in-cache (current-buffer))
156 (when (or (search-forward "\n\n" nil t)
157 (search-forward "\r\n\r\n" nil t))
158 (let ((data (buffer-substring (point) (point-max))))
159 (with-current-buffer buffer
160 (let ((alt (buffer-substring start end))
161 (inhibit-read-only t))
162 (delete-region start end)
163 (shr-put-image data start alt))))))
164 (kill-buffer (current-buffer)))
165
166(defun shr-put-image (data point alt)
167 (if (not (display-graphic-p))
168 (insert alt)
169 (let ((image (shr-rescale-image data)))
170 (put-image image point alt))))
171
172(defun shr-rescale-image (data)
173 (if (or (not (fboundp 'imagemagick-types))
174 (not (get-buffer-window (current-buffer))))
175 (create-image data nil t)
176 (let* ((image (create-image data nil t))
177 (size (image-size image))
178 (width (car size))
179 (height (cdr size))
180 (edges (window-inside-pixel-edges
181 (get-buffer-window (current-buffer))))
182 (window-width (truncate (* shr-max-image-proportion
183 (- (nth 2 edges) (nth 0 edges)))))
184 (window-height (truncate (* shr-max-image-proportion
185 (- (nth 3 edges) (nth 1 edges)))))
186 scaled-image)
187 (when (> height window-height)
188 (setq image (or (create-image data 'imagemagick t
189 :height window-height)
190 image))
191 (setq size (image-size image t)))
192 (when (> (car size) window-width)
193 (setq image (or
194 (create-image data 'imagemagick t
195 :width window-width)
196 image)))
197 image)))
198
199(defun shr-pre (cont)
200 (let ((shr-folding-mode nil))
201 (shr-ensure-newline)
202 (shr-generic cont)
203 (shr-ensure-newline)))
204
205(defun shr-blockquote (cont)
206 (shr-pre cont))
207
208(defun shr-ensure-newline ()
209 (unless (zerop (current-column))
210 (insert "\n")))
211
212(defun shr-insert (text)
213 (when (eq shr-state 'image)
214 (insert "\n")
215 (setq shr-state nil))
216 (cond
217 ((eq shr-folding-mode 'none)
218 (insert t))
219 (t
220 (let (column)
221 (dolist (elem (split-string text))
222 (setq column (current-column))
223 (when (plusp column)
224 (if (> (+ column (length elem) 1) shr-width)
225 (insert "\n")
226 (insert " ")))
227 ;; The shr-start is a special variable that is used to pass
228 ;; upwards the first point in the buffer where the text really
229 ;; starts.
230 (unless shr-start
231 (setq shr-start (point)))
232 (insert elem))))))
233
234(defun shr-get-image-data (url)
235 "Get image data for URL.
236Return a string with image data."
237 (with-temp-buffer
238 (mm-disable-multibyte)
239 (url-cache-extract (url-cache-create-filename url))
240 (when (or (search-forward "\n\n" nil t)
241 (search-forward "\r\n\r\n" nil t))
242 (buffer-substring (point) (point-max)))))
243
33(provide 'shr) 244(provide 'shr)
34 245
35;;; shr.el ends here 246;;; shr.el ends here