diff options
| author | Gnus developers | 2010-10-03 00:33:27 +0000 |
|---|---|---|
| committer | Katsumi Yamaoka | 2010-10-03 00:33:27 +0000 |
| commit | 870409d4fb06834c28e75cd653ad8aa2a7e8f581 (patch) | |
| tree | 8068a94b7d19168f48eef4ea22c081ca1c031209 | |
| parent | 2a847524ab57b1b3d6eaa7e12b96be52dbb79509 (diff) | |
| download | emacs-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/ChangeLog | 1 | ||||
| -rw-r--r-- | doc/misc/gnus.texi | 2 | ||||
| -rw-r--r-- | lisp/gnus/ChangeLog | 25 | ||||
| -rw-r--r-- | lisp/gnus/gnus-gravatar.el | 2 | ||||
| -rw-r--r-- | lisp/gnus/gnus-html.el | 28 | ||||
| -rw-r--r-- | lisp/gnus/gnus-util.el | 63 | ||||
| -rw-r--r-- | lisp/gnus/mm-decode.el | 11 | ||||
| -rw-r--r-- | lisp/gnus/shr.el | 211 |
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 @@ | |||
| 1 | 2010-10-02 Lars Magne Ingebrigtsen <larsi@gnus.org> | 1 | 2010-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 | ||
| 5 | 2010-10-01 Lars Magne Ingebrigtsen <larsi@gnus.org> | 6 | 2010-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 | |||
| 15111 | thinks should carry this mail message. | 15111 | thinks should carry this mail message. |
| 15112 | 15112 | ||
| 15113 | This variable can also be a fancy split method. For the syntax, | 15113 | This variable can also be a fancy split method. For the syntax, |
| 15114 | @pxref{Fancy Mail Splitting}. | 15114 | see @ref{Fancy Mail Splitting}. |
| 15115 | 15115 | ||
| 15116 | Note that the mail back ends are free to maul the poor, innocent, | 15116 | Note that the mail back ends are free to maul the poor, innocent, |
| 15117 | incoming headers all they want to. They all add @code{Lines} headers; | 15117 | incoming 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 @@ | |||
| 1 | 2010-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 | |||
| 9 | 2010-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 | |||
| 21 | 2010-10-02 Julien Danjou <julien@danjou.info> | ||
| 22 | |||
| 23 | * gnus-gravatar.el (gnus-gravatar-insert): Adjust character where we | ||
| 24 | should go backward. | ||
| 25 | |||
| 1 | 2010-10-02 Juanma Barranquero <lekktu@gmail.com> | 26 | 2010-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'." |
| 1589 | Depends 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. | ||
| 39 | A value of 0.7 means that they are allowed to take up 70% of the | ||
| 40 | width and height of the window. If they are larger than this, | ||
| 41 | and Emacs supports it, then the images will be rescaled down to | ||
| 42 | fit 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. | ||
| 236 | Return 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 |