diff options
| author | Gnus developers | 2013-06-16 22:20:55 +0000 |
|---|---|---|
| committer | Katsumi Yamaoka | 2013-06-16 22:20:55 +0000 |
| commit | c74cb3449a0c0e54f79ecec93886a0737326e033 (patch) | |
| tree | 810b66eda9c360f1d365b145b0caf0284f7b3bf4 | |
| parent | 28237e48e122aa8cbd9b7bea8d3d5d15b8181666 (diff) | |
| download | emacs-c74cb3449a0c0e54f79ecec93886a0737326e033.tar.gz emacs-c74cb3449a0c0e54f79ecec93886a0737326e033.zip | |
2013-06-16 Lars Magne Ingebrigtsen <larsi@gnus.org>
* eww.el (eww-display-html): Default to using the entire window width.
* shr.el (shr-make-table): Cache the table rendering at the table level, and not the <td> level. This is a bit faster.
* eww.el (eww-render): Go to the correct ID when given URLs ending with #id.
* shr.el (shr-tag-li): Don't require a new paragraph, since other browsers don't.
(shr-expand-url): Respect #anchor links.
(shr-parse-base): Chop off the anchor before using.
(shr-descend): Respect display: none.
(shr-descend): Allow marking elements that have certain IDs.
* eww.el (eww-tag-textarea): Use `text' instead of `editable-field'.
* shr.el (shr-expand-url): Don't bug out on zero-length links.
* eww.el (eww-tag-textarea): Support <textarea>.
2013-06-16 RĂ¼diger Sonderfeld <ruediger@c-plusplus.de>
* shr.el (shr-dom-to-xml): Fixed function call.
* eww.el (eww): New group.
(eww-header-line-format): New custom variable.
(eww-current-title): New variable.
(eww-display-html): Update header and handle title tag.
(eww-update-header-line-format): New function.
(eww-tag-title): New function.
* shr.el (shr-dom-to-xml): (shr-dom-to-xml): New function.
(shr-tag-svg): Add support for the SVG tag.
(shr-bullet): New custom variable.
(shr-tag-li): Support custom bullet in unordered lists.
2013-06-16 Lars Magne Ingebrigtsen <larsi@gnus.org>
* shr.el (shr-expand-url): Respect // URLs.
* eww.el (eww-tag-body): Override the shr body rendering so that we can
put a background colour onto the entire buffer.
(eww-render): When being redirected, use the redirect URL as the new
base URL.
* shr.el (shr-parse-base): Fix parsing error.
* eww.el (eww-submit): Pass the base in to `shr-expand-url'.
* shr.el (shr-parse-base): New function.
(shr-expand-url): Use it to expand relative URLs reliably.
| -rw-r--r-- | lisp/gnus/ChangeLog | 55 | ||||
| -rw-r--r-- | lisp/gnus/eww.el | 121 | ||||
| -rw-r--r-- | lisp/gnus/shr.el | 177 |
3 files changed, 270 insertions, 83 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 33ae989d15a..58b5ae1a56a 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog | |||
| @@ -1,3 +1,58 @@ | |||
| 1 | 2013-06-16 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 2 | |||
| 3 | * eww.el (eww-display-html): Default to using the entire window width. | ||
| 4 | |||
| 5 | * shr.el (shr-make-table): Cache the table rendering at the table | ||
| 6 | level, and not the <td> level. This is a bit faster. | ||
| 7 | |||
| 8 | * eww.el (eww-render): Go to the correct ID when given URLs ending with | ||
| 9 | #id. | ||
| 10 | |||
| 11 | * shr.el (shr-tag-li): Don't require a new paragraph, since other | ||
| 12 | browsers don't. | ||
| 13 | (shr-expand-url): Respect #anchor links. | ||
| 14 | (shr-parse-base): Chop off the anchor before using. | ||
| 15 | (shr-descend): Respect display: none. | ||
| 16 | (shr-descend): Allow marking elements that have certain IDs. | ||
| 17 | |||
| 18 | * eww.el (eww-tag-textarea): Use `text' instead of `editable-field'. | ||
| 19 | |||
| 20 | * shr.el (shr-expand-url): Don't bug out on zero-length links. | ||
| 21 | |||
| 22 | * eww.el (eww-tag-textarea): Support <textarea>. | ||
| 23 | |||
| 24 | 2013-06-16 RĂ¼diger Sonderfeld <ruediger@c-plusplus.de> | ||
| 25 | |||
| 26 | * shr.el (shr-dom-to-xml): Fixed function call. | ||
| 27 | |||
| 28 | * eww.el (eww): New group. | ||
| 29 | (eww-header-line-format): New custom variable. | ||
| 30 | (eww-current-title): New variable. | ||
| 31 | (eww-display-html): Update header and handle title tag. | ||
| 32 | (eww-update-header-line-format): New function. | ||
| 33 | (eww-tag-title): New function. | ||
| 34 | |||
| 35 | * shr.el (shr-dom-to-xml): (shr-dom-to-xml): New function. | ||
| 36 | (shr-tag-svg): Add support for the SVG tag. | ||
| 37 | (shr-bullet): New custom variable. | ||
| 38 | (shr-tag-li): Support custom bullet in unordered lists. | ||
| 39 | |||
| 40 | 2013-06-16 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 41 | |||
| 42 | * shr.el (shr-expand-url): Respect // URLs. | ||
| 43 | |||
| 44 | * eww.el (eww-tag-body): Override the shr body rendering so that we can | ||
| 45 | put a background colour onto the entire buffer. | ||
| 46 | (eww-render): When being redirected, use the redirect URL as the new | ||
| 47 | base URL. | ||
| 48 | |||
| 49 | * shr.el (shr-parse-base): Fix parsing error. | ||
| 50 | |||
| 51 | * eww.el (eww-submit): Pass the base in to `shr-expand-url'. | ||
| 52 | |||
| 53 | * shr.el (shr-parse-base): New function. | ||
| 54 | (shr-expand-url): Use it to expand relative URLs reliably. | ||
| 55 | |||
| 1 | 2013-06-15 Teodor Zlatanov <tzz@lifelogs.com> | 56 | 2013-06-15 Teodor Zlatanov <tzz@lifelogs.com> |
| 2 | 57 | ||
| 3 | * auth-source.el (auth-source-search-collection): Fix docstring. | 58 | * auth-source.el (auth-source-search-collection): Fix docstring. |
diff --git a/lisp/gnus/eww.el b/lisp/gnus/eww.el index 270c3ee3ed2..b34ec7655cc 100644 --- a/lisp/gnus/eww.el +++ b/lisp/gnus/eww.el | |||
| @@ -29,7 +29,22 @@ | |||
| 29 | (require 'url) | 29 | (require 'url) |
| 30 | (require 'mm-url) | 30 | (require 'mm-url) |
| 31 | 31 | ||
| 32 | (defgroup eww nil | ||
| 33 | "Emacs Web Wowser" | ||
| 34 | :version "24.4" | ||
| 35 | :group 'hypermedia | ||
| 36 | :prefix "eww-") | ||
| 37 | |||
| 38 | (defcustom eww-header-line-format "%t: %u" | ||
| 39 | "Header line format. | ||
| 40 | - %t is replaced by the title. | ||
| 41 | - %u is replaced by the URL." | ||
| 42 | :group 'eww | ||
| 43 | :type 'string) | ||
| 44 | |||
| 32 | (defvar eww-current-url nil) | 45 | (defvar eww-current-url nil) |
| 46 | (defvar eww-current-title "" | ||
| 47 | "Title of current page.") | ||
| 33 | (defvar eww-history nil) | 48 | (defvar eww-history nil) |
| 34 | 49 | ||
| 35 | ;;;###autoload | 50 | ;;;###autoload |
| @@ -53,7 +68,13 @@ | |||
| 53 | (match-string 1))))) | 68 | (match-string 1))))) |
| 54 | 69 | ||
| 55 | (defun eww-render (status url &optional point) | 70 | (defun eww-render (status url &optional point) |
| 71 | (let ((redirect (plist-get status :redirect))) | ||
| 72 | (when redirect | ||
| 73 | (setq url redirect))) | ||
| 56 | (let* ((headers (eww-parse-headers)) | 74 | (let* ((headers (eww-parse-headers)) |
| 75 | (shr-target-id | ||
| 76 | (and (string-match "#\\(.*\\)" url) | ||
| 77 | (match-string 1 url))) | ||
| 57 | (content-type | 78 | (content-type |
| 58 | (mail-header-parse-content-type | 79 | (mail-header-parse-content-type |
| 59 | (or (cdr (assoc "content-type" headers)) | 80 | (or (cdr (assoc "content-type" headers)) |
| @@ -74,8 +95,14 @@ | |||
| 74 | (eww-display-image)) | 95 | (eww-display-image)) |
| 75 | (t | 96 | (t |
| 76 | (eww-display-raw charset))) | 97 | (eww-display-raw charset))) |
| 77 | (when point | 98 | (cond |
| 78 | (goto-char point))) | 99 | (point |
| 100 | (goto-char point)) | ||
| 101 | (shr-target-id | ||
| 102 | (let ((point (next-single-property-change | ||
| 103 | (point-min) 'shr-target-id))) | ||
| 104 | (when point | ||
| 105 | (goto-char (1+ point))))))) | ||
| 79 | (kill-buffer data-buffer)))) | 106 | (kill-buffer data-buffer)))) |
| 80 | 107 | ||
| 81 | (defun eww-parse-headers () | 108 | (defun eww-parse-headers () |
| @@ -101,15 +128,56 @@ | |||
| 101 | (libxml-parse-html-region (point) (point-max))))) | 128 | (libxml-parse-html-region (point) (point-max))))) |
| 102 | (eww-setup-buffer) | 129 | (eww-setup-buffer) |
| 103 | (setq eww-current-url url) | 130 | (setq eww-current-url url) |
| 131 | (eww-update-header-line-format) | ||
| 104 | (let ((inhibit-read-only t) | 132 | (let ((inhibit-read-only t) |
| 133 | (shr-width nil) | ||
| 105 | (shr-external-rendering-functions | 134 | (shr-external-rendering-functions |
| 106 | '((form . eww-tag-form) | 135 | '((title . eww-tag-title) |
| 136 | (form . eww-tag-form) | ||
| 107 | (input . eww-tag-input) | 137 | (input . eww-tag-input) |
| 138 | (textarea . eww-tag-textarea) | ||
| 139 | (body . eww-tag-body) | ||
| 108 | (select . eww-tag-select)))) | 140 | (select . eww-tag-select)))) |
| 109 | (shr-insert-document document) | 141 | (shr-insert-document document) |
| 110 | (eww-convert-widgets)) | 142 | (eww-convert-widgets)) |
| 111 | (goto-char (point-min)))) | 143 | (goto-char (point-min)))) |
| 112 | 144 | ||
| 145 | (defun eww-update-header-line-format () | ||
| 146 | (if eww-header-line-format | ||
| 147 | (setq header-line-format (format-spec eww-header-line-format | ||
| 148 | `((?u . ,eww-current-url) | ||
| 149 | (?t . ,eww-current-title)))) | ||
| 150 | (setq header-line-format nil))) | ||
| 151 | |||
| 152 | (defun eww-tag-title (cont) | ||
| 153 | (setq eww-current-title "") | ||
| 154 | (dolist (sub cont) | ||
| 155 | (when (eq (car sub) 'text) | ||
| 156 | (setq eww-current-title (concat eww-current-title (cdr sub))))) | ||
| 157 | (eww-update-header-line-format)) | ||
| 158 | |||
| 159 | (defun eww-tag-body (cont) | ||
| 160 | (let* ((start (point)) | ||
| 161 | (fgcolor (cdr (or (assq :fgcolor cont) | ||
| 162 | (assq :text cont)))) | ||
| 163 | (bgcolor (cdr (assq :bgcolor cont))) | ||
| 164 | (shr-stylesheet (list (cons 'color fgcolor) | ||
| 165 | (cons 'background-color bgcolor)))) | ||
| 166 | (shr-generic cont) | ||
| 167 | (eww-colorize-region start (point) fgcolor bgcolor))) | ||
| 168 | |||
| 169 | (defun eww-colorize-region (start end fg &optional bg) | ||
| 170 | (when (or fg bg) | ||
| 171 | (let ((new-colors (shr-color-check fg bg))) | ||
| 172 | (when new-colors | ||
| 173 | (when fg | ||
| 174 | (eww-put-color start end :foreground (cadr new-colors))) | ||
| 175 | (when bg | ||
| 176 | (eww-put-color start end :background (car new-colors))))))) | ||
| 177 | |||
| 178 | (defun eww-put-color (start end type color) | ||
| 179 | (shr-put-color-1 start end type color)) | ||
| 180 | |||
| 113 | (defun eww-display-raw (charset) | 181 | (defun eww-display-raw (charset) |
| 114 | (let ((data (buffer-substring (point) (point-max)))) | 182 | (let ((data (buffer-substring (point) (point-max)))) |
| 115 | (eww-setup-buffer) | 183 | (eww-setup-buffer) |
| @@ -240,6 +308,21 @@ | |||
| 240 | (apply 'widget-create widget) | 308 | (apply 'widget-create widget) |
| 241 | (put-text-property start (point) 'eww-widget widget)))) | 309 | (put-text-property start (point) 'eww-widget widget)))) |
| 242 | 310 | ||
| 311 | (defun eww-tag-textarea (cont) | ||
| 312 | (let* ((start (point)) | ||
| 313 | (widget | ||
| 314 | (list 'text | ||
| 315 | :size (string-to-number | ||
| 316 | (or (cdr (assq :cols cont)) | ||
| 317 | "40")) | ||
| 318 | :value (or (cdr (assq 'text cont)) "") | ||
| 319 | :action 'eww-submit | ||
| 320 | :name (cdr (assq :name cont)) | ||
| 321 | :eww-form eww-form))) | ||
| 322 | (nconc eww-form (list widget)) | ||
| 323 | (apply 'widget-create widget) | ||
| 324 | (put-text-property start (point) 'eww-widget widget))) | ||
| 325 | |||
| 243 | (defun eww-tag-select (cont) | 326 | (defun eww-tag-select (cont) |
| 244 | (shr-ensure-paragraph) | 327 | (shr-ensure-paragraph) |
| 245 | (let ((menu (list 'menu-choice | 328 | (let ((menu (list 'menu-choice |
| @@ -330,22 +413,22 @@ | |||
| 330 | (plist-get (cdr elem) :value)) | 413 | (plist-get (cdr elem) :value)) |
| 331 | values) | 414 | values) |
| 332 | (setq rest nil)))))) | 415 | (setq rest nil)))))) |
| 333 | (debug values) | 416 | (if (and (stringp (cdr (assq :method form))) |
| 334 | (let ((shr-base eww-current-url)) | 417 | (equal (downcase (cdr (assq :method form))) "post")) |
| 335 | (if (and (stringp (cdr (assq :method form))) | 418 | (let ((url-request-method "POST") |
| 336 | (equal (downcase (cdr (assq :method form))) "post")) | 419 | (url-request-extra-headers |
| 337 | (let ((url-request-method "POST") | 420 | '(("Content-Type" . "application/x-www-form-urlencoded"))) |
| 338 | (url-request-extra-headers | 421 | (url-request-data (mm-url-encode-www-form-urlencoded values))) |
| 339 | '(("Content-Type" . "application/x-www-form-urlencoded"))) | 422 | (eww-browse-url (shr-expand-url (cdr (assq :action form)) |
| 340 | (url-request-data (mm-url-encode-www-form-urlencoded values))) | 423 | eww-current-url))) |
| 341 | (eww-browse-url (shr-expand-url (cdr (assq :action form))))) | 424 | (eww-browse-url |
| 342 | (eww-browse-url | 425 | (concat |
| 343 | (concat | 426 | (if (cdr (assq :action form)) |
| 344 | (if (cdr (assq :action form)) | 427 | (shr-expand-url (cdr (assq :action form)) |
| 345 | (shr-expand-url (cdr (assq :action form))) | 428 | eww-current-url) |
| 346 | eww-current-url) | 429 | eww-current-url) |
| 347 | "?" | 430 | "?" |
| 348 | (mm-url-encode-www-form-urlencoded values))))))) | 431 | (mm-url-encode-www-form-urlencoded values)))))) |
| 349 | 432 | ||
| 350 | (defun eww-convert-widgets () | 433 | (defun eww-convert-widgets () |
| 351 | (let ((start (point-min)) | 434 | (let ((start (point-min)) |
diff --git a/lisp/gnus/shr.el b/lisp/gnus/shr.el index c93357efd25..339b9698922 100644 --- a/lisp/gnus/shr.el +++ b/lisp/gnus/shr.el | |||
| @@ -83,6 +83,14 @@ used." | |||
| 83 | (const :tag "Use the width of the window" nil)) | 83 | (const :tag "Use the width of the window" nil)) |
| 84 | :group 'shr) | 84 | :group 'shr) |
| 85 | 85 | ||
| 86 | (defcustom shr-bullet "* " | ||
| 87 | "Bullet used for unordered lists. | ||
| 88 | Alternative suggestions are: | ||
| 89 | - \" \" | ||
| 90 | - \" \"" | ||
| 91 | :type 'string | ||
| 92 | :group 'shr) | ||
| 93 | |||
| 86 | (defvar shr-content-function nil | 94 | (defvar shr-content-function nil |
| 87 | "If bound, this should be a function that will return the content. | 95 | "If bound, this should be a function that will return the content. |
| 88 | This is used for cid: URLs, and the function is called with the | 96 | This is used for cid: URLs, and the function is called with the |
| @@ -115,6 +123,7 @@ cid: URL as the argument.") | |||
| 115 | (defvar shr-base nil) | 123 | (defvar shr-base nil) |
| 116 | (defvar shr-ignore-cache nil) | 124 | (defvar shr-ignore-cache nil) |
| 117 | (defvar shr-external-rendering-functions nil) | 125 | (defvar shr-external-rendering-functions nil) |
| 126 | (defvar shr-target-id nil) | ||
| 118 | 127 | ||
| 119 | (defvar shr-map | 128 | (defvar shr-map |
| 120 | (let ((map (make-sparse-keymap))) | 129 | (let ((map (make-sparse-keymap))) |
| @@ -303,18 +312,24 @@ size, and full-buffer size." | |||
| 303 | (shr-stylesheet shr-stylesheet) | 312 | (shr-stylesheet shr-stylesheet) |
| 304 | (start (point))) | 313 | (start (point))) |
| 305 | (when style | 314 | (when style |
| 306 | (if (string-match "color" style) | 315 | (if (string-match "color\\|display" style) |
| 307 | (setq shr-stylesheet (nconc (shr-parse-style style) | 316 | (setq shr-stylesheet (nconc (shr-parse-style style) |
| 308 | shr-stylesheet)) | 317 | shr-stylesheet)) |
| 309 | (setq style nil))) | 318 | (setq style nil))) |
| 310 | (if (fboundp function) | 319 | ;; If we have a display:none, then just ignore this part of the |
| 311 | (funcall function (cdr dom)) | 320 | ;; DOM. |
| 312 | (shr-generic (cdr dom))) | 321 | (unless (equal (cdr (assq 'display shr-stylesheet)) "none") |
| 313 | ;; If style is set, then this node has set the color. | 322 | (if (fboundp function) |
| 314 | (when style | 323 | (funcall function (cdr dom)) |
| 315 | (shr-colorize-region start (point) | 324 | (shr-generic (cdr dom))) |
| 316 | (cdr (assq 'color shr-stylesheet)) | 325 | (when (and shr-target-id |
| 317 | (cdr (assq 'background-color shr-stylesheet)))))) | 326 | (equal (cdr (assq :id (cdr dom))) shr-target-id)) |
| 327 | (put-text-property start (1+ start) 'shr-target-id shr-target-id)) | ||
| 328 | ;; If style is set, then this node has set the color. | ||
| 329 | (when style | ||
| 330 | (shr-colorize-region start (point) | ||
| 331 | (cdr (assq 'color shr-stylesheet)) | ||
| 332 | (cdr (assq 'background-color shr-stylesheet))))))) | ||
| 318 | 333 | ||
| 319 | (defun shr-generic (cont) | 334 | (defun shr-generic (cont) |
| 320 | (dolist (sub cont) | 335 | (dolist (sub cont) |
| @@ -484,31 +499,51 @@ size, and full-buffer size." | |||
| 484 | (forward-char 1)))) | 499 | (forward-char 1)))) |
| 485 | (not failed))) | 500 | (not failed))) |
| 486 | 501 | ||
| 487 | (defun shr-expand-url (url) | 502 | (defun shr-parse-base (url) |
| 488 | (if (or (not url) | 503 | ;; Always chop off anchors. |
| 489 | (string-match "\\`[a-z]*:" url) | 504 | (when (string-match "#.*" url) |
| 490 | (not shr-base)) | 505 | (setq url (substring url 0 (match-beginning 0)))) |
| 491 | ;; Absolute URL. | 506 | (let* ((parsed (url-generic-parse-url url)) |
| 492 | url | 507 | (local (url-filename parsed))) |
| 493 | (let ((base shr-base)) | 508 | (setf (url-filename parsed) "") |
| 494 | ;; Chop off query string. | 509 | ;; Chop off the bit after the last slash. |
| 495 | (when (string-match "\\`\\([^?]+\\)[?]" base) | 510 | (when (string-match "\\`\\(.*/\\)[^/]+\\'" local) |
| 496 | (setq base (match-string 1 base))) | 511 | (setq local (match-string 1 local))) |
| 497 | ;; Chop off the bit after the last slash. | 512 | ;; Always make the local bit end with a slash. |
| 498 | (when (string-match "\\`\\(.*\\)[/][^/]+" base) | 513 | (when (and (not (zerop (length local))) |
| 499 | (setq base (match-string 1 base))) | 514 | (not (eq (aref local (1- (length local))) ?/))) |
| 500 | (cond | 515 | (setq local (concat local "/"))) |
| 501 | ((and (string-match "\\`//" url) | 516 | (list (url-recreate-url parsed) |
| 502 | (string-match "\\`[a-z]*:" base)) | 517 | local |
| 503 | (concat (match-string 0 base) url)) | 518 | (url-type parsed) |
| 504 | ((and (not (string-match "/\\'" base)) | 519 | url))) |
| 505 | (not (string-match "\\`/" url))) | 520 | |
| 506 | (concat base "/" url)) | 521 | (defun shr-expand-url (url &optional base) |
| 507 | ((and (string-match "\\`/" url) | 522 | (setq base |
| 508 | (string-match "\\(\\`[^:]*://[^/]+\\)/" base)) | 523 | (if base |
| 509 | (concat (match-string 1 base) url)) | 524 | (shr-parse-base base) |
| 510 | (t | 525 | ;; Bound by the parser. |
| 511 | (concat base url)))))) | 526 | shr-base)) |
| 527 | (when (zerop (length url)) | ||
| 528 | (setq url nil)) | ||
| 529 | (cond ((or (not url) | ||
| 530 | (not base) | ||
| 531 | (string-match "\\`[a-z]*:" url)) | ||
| 532 | ;; Absolute URL. | ||
| 533 | (or url (car base))) | ||
| 534 | ((eq (aref url 0) ?/) | ||
| 535 | (if (and (> (length url) 1) | ||
| 536 | (eq (aref url 1) ?/)) | ||
| 537 | ;; //host...; just use the protocol | ||
| 538 | (concat (nth 2 base) ":" url) | ||
| 539 | ;; Just use the host name part. | ||
| 540 | (concat (car base) url))) | ||
| 541 | ((eq (aref url 0) ?#) | ||
| 542 | ;; A link to an anchor. | ||
| 543 | (concat (nth 3 base) url)) | ||
| 544 | (t | ||
| 545 | ;; Totally relative. | ||
| 546 | (concat (car base) (cadr base) url)))) | ||
| 512 | 547 | ||
| 513 | (defun shr-ensure-newline () | 548 | (defun shr-ensure-newline () |
| 514 | (unless (zerop (current-column)) | 549 | (unless (zerop (current-column)) |
| @@ -894,8 +929,31 @@ ones, in case fg and bg are nil." | |||
| 894 | (defun shr-tag-comment (cont) | 929 | (defun shr-tag-comment (cont) |
| 895 | ) | 930 | ) |
| 896 | 931 | ||
| 932 | (defun shr-dom-to-xml (dom) | ||
| 933 | "Convert DOM into a string containing the xml representation." | ||
| 934 | (let ((arg " ") | ||
| 935 | (text "")) | ||
| 936 | (dolist (sub (cdr dom)) | ||
| 937 | (cond | ||
| 938 | ((listp (cdr sub)) | ||
| 939 | (setq text (concat text (shr-dom-to-xml sub)))) | ||
| 940 | ((eq (car sub) 'text) | ||
| 941 | (setq text (concat text (cdr sub)))) | ||
| 942 | (t | ||
| 943 | (setq arg (concat arg (format "%s=\"%s\" " | ||
| 944 | (substring (symbol-name (car sub)) 1) | ||
| 945 | (cdr sub))))))) | ||
| 946 | (format "<%s%s>%s</%s>" | ||
| 947 | (car dom) | ||
| 948 | (substring arg 0 (1- (length arg))) | ||
| 949 | text | ||
| 950 | (car dom)))) | ||
| 951 | |||
| 897 | (defun shr-tag-svg (cont) | 952 | (defun shr-tag-svg (cont) |
| 898 | ) | 953 | (when (image-type-available-p 'svg) |
| 954 | (funcall shr-put-image-function | ||
| 955 | (shr-dom-to-xml (cons 'svg cont)) | ||
| 956 | "SVG Image"))) | ||
| 899 | 957 | ||
| 900 | (defun shr-tag-sup (cont) | 958 | (defun shr-tag-sup (cont) |
| 901 | (let ((start (point))) | 959 | (let ((start (point))) |
| @@ -965,7 +1023,7 @@ ones, in case fg and bg are nil." | |||
| 965 | plist))) | 1023 | plist))) |
| 966 | 1024 | ||
| 967 | (defun shr-tag-base (cont) | 1025 | (defun shr-tag-base (cont) |
| 968 | (setq shr-base (cdr (assq :href cont))) | 1026 | (setq shr-base (shr-parse-base (cdr (assq :href cont)))) |
| 969 | (shr-generic cont)) | 1027 | (shr-generic cont)) |
| 970 | 1028 | ||
| 971 | (defun shr-tag-a (cont) | 1029 | (defun shr-tag-a (cont) |
| @@ -1087,14 +1145,14 @@ ones, in case fg and bg are nil." | |||
| 1087 | (shr-ensure-paragraph)) | 1145 | (shr-ensure-paragraph)) |
| 1088 | 1146 | ||
| 1089 | (defun shr-tag-li (cont) | 1147 | (defun shr-tag-li (cont) |
| 1090 | (shr-ensure-paragraph) | 1148 | (shr-ensure-newline) |
| 1091 | (shr-indent) | 1149 | (shr-indent) |
| 1092 | (let* ((bullet | 1150 | (let* ((bullet |
| 1093 | (if (numberp shr-list-mode) | 1151 | (if (numberp shr-list-mode) |
| 1094 | (prog1 | 1152 | (prog1 |
| 1095 | (format "%d " shr-list-mode) | 1153 | (format "%d " shr-list-mode) |
| 1096 | (setq shr-list-mode (1+ shr-list-mode))) | 1154 | (setq shr-list-mode (1+ shr-list-mode))) |
| 1097 | "* ")) | 1155 | shr-bullet)) |
| 1098 | (shr-indentation (+ shr-indentation (length bullet)))) | 1156 | (shr-indentation (+ shr-indentation (length bullet)))) |
| 1099 | (insert bullet) | 1157 | (insert bullet) |
| 1100 | (shr-generic cont))) | 1158 | (shr-generic cont))) |
| @@ -1352,6 +1410,13 @@ ones, in case fg and bg are nil." | |||
| 1352 | widths)) | 1410 | widths)) |
| 1353 | 1411 | ||
| 1354 | (defun shr-make-table (cont widths &optional fill) | 1412 | (defun shr-make-table (cont widths &optional fill) |
| 1413 | (or (cadr (assoc (list cont widths fill) shr-content-cache)) | ||
| 1414 | (let ((data (shr-make-table-1 cont widths fill))) | ||
| 1415 | (push (list (list cont widths fill) data) | ||
| 1416 | shr-content-cache) | ||
| 1417 | data))) | ||
| 1418 | |||
| 1419 | (defun shr-make-table-1 (cont widths &optional fill) | ||
| 1355 | (let ((trs nil)) | 1420 | (let ((trs nil)) |
| 1356 | (dolist (row cont) | 1421 | (dolist (row cont) |
| 1357 | (when (eq (car row) 'tr) | 1422 | (when (eq (car row) 'tr) |
| @@ -1385,32 +1450,16 @@ ones, in case fg and bg are nil." | |||
| 1385 | (setq style (nconc (list (cons 'color fgcolor)) style))) | 1450 | (setq style (nconc (list (cons 'color fgcolor)) style))) |
| 1386 | (when style | 1451 | (when style |
| 1387 | (setq shr-stylesheet (append style shr-stylesheet))) | 1452 | (setq shr-stylesheet (append style shr-stylesheet))) |
| 1388 | (let ((cache (cdr (assoc (cons width cont) shr-content-cache)))) | 1453 | (let ((shr-width width) |
| 1389 | (if cache | 1454 | (shr-indentation 0)) |
| 1390 | (progn | 1455 | (shr-descend (cons 'td cont))) |
| 1391 | (insert (car cache)) | 1456 | ;; Delete padding at the bottom of the TDs. |
| 1392 | (let ((end (length (car cache)))) | 1457 | (delete-region |
| 1393 | (dolist (overlay (cadr cache)) | 1458 | (point) |
| 1394 | (let ((new-overlay | 1459 | (progn |
| 1395 | (shr-make-overlay (1+ (- end (nth 0 overlay))) | 1460 | (skip-chars-backward " \t\n") |
| 1396 | (1+ (- end (nth 1 overlay))))) | 1461 | (end-of-line) |
| 1397 | (properties (nth 2 overlay))) | 1462 | (point))) |
| 1398 | (while properties | ||
| 1399 | (overlay-put new-overlay | ||
| 1400 | (pop properties) (pop properties))))))) | ||
| 1401 | (let ((shr-width width) | ||
| 1402 | (shr-indentation 0)) | ||
| 1403 | (shr-descend (cons 'td cont))) | ||
| 1404 | ;; Delete padding at the bottom of the TDs. | ||
| 1405 | (delete-region | ||
| 1406 | (point) | ||
| 1407 | (progn | ||
| 1408 | (skip-chars-backward " \t\n") | ||
| 1409 | (end-of-line) | ||
| 1410 | (point))) | ||
| 1411 | (push (list (cons width cont) (buffer-string) | ||
| 1412 | (shr-overlays-in-region (point-min) (point-max))) | ||
| 1413 | shr-content-cache))) | ||
| 1414 | (goto-char (point-min)) | 1463 | (goto-char (point-min)) |
| 1415 | (let ((max 0)) | 1464 | (let ((max 0)) |
| 1416 | (while (not (eobp)) | 1465 | (while (not (eobp)) |