diff options
| author | Lars Magne Ingebrigtsen | 2015-02-10 16:29:05 +1100 |
|---|---|---|
| committer | Lars Magne Ingebrigtsen | 2015-02-10 16:29:05 +1100 |
| commit | 656caef3505e11b073d59b9c18d3fd21e199d77c (patch) | |
| tree | 81428a27129c5095c97f73a3741242d20af48b99 | |
| parent | 880415a6a6ec90bd9bf8467a43a41973f78260b3 (diff) | |
| download | emacs-656caef3505e11b073d59b9c18d3fd21e199d77c.tar.gz emacs-656caef3505e11b073d59b9c18d3fd21e199d77c.zip | |
Allow using variable-width fonts in eww
* lisp/gnus/mm-decode.el (mm-shr): Only pass the fill column when not using
fonts, because limiting the width to what's appropriate for followups
doesn't really help when not using proportional fonts.
* lisp/net/shr.el (shr-use-fonts): New variable.
(shr-fill-text): Rename from "fold".
(shr-pixel-column, shr-pixel-region, shr-string-pixel-width): New
functions.
(shr-insert): Just insert, don't fill the text. Filling is now
done afterwards per display unit.
(shr-fill-lines, shr-fill-line): New functions to fill text on a
per-unit base.
(shr-find-fill-point): Take a "beginning" parameter.
(shr-indent): Indent using the :width display parameter when using
fonts.
(shr-parse-style): Ignore "inherit" values, since we already do that.
(shr-tag-img): Remove the insertion states.
(shr-tag-blockquote): New-style filling.
(shr-tag-dd): Ditto.
(shr-tag-li): Ditto.
(shr-mark-fill): New function to mark lines that need filling.
(shr-tag-h1): Use a larger font.
(shr-tag-table-1): Get the natural and suggested widths in one
rendering.
(shr-tag-table): Create the "fixed" version of the table only once
so that we can cache data in the table.
(shr-insert-table): Get colspan calculations right by having
zero-width columns after colspan ones.
(shr-expand-alignments): New function to make :align-to specs work
right when rendered in one buffer and displayed in another one.
(shr-insert-table-ruler): Use :align-to to get the widths right.
(shr-make-table): Cache more.
(shr-make-table-1): Use the new <td> data layout.
(shr-pixel-buffer-width): New function.
(shr-render-td): Add a caching layer.
(shr-dom-max-natural-width): New function.
| -rw-r--r-- | lisp/ChangeLog | 35 | ||||
| -rw-r--r-- | lisp/gnus/ChangeLog | 12 | ||||
| -rw-r--r-- | lisp/gnus/mm-decode.el | 9 | ||||
| -rw-r--r-- | lisp/net/eww.el | 20 | ||||
| -rw-r--r-- | lisp/net/shr.el | 701 |
5 files changed, 513 insertions, 264 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f7dcb840bd6..d8cb245cbeb 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,38 @@ | |||
| 1 | 2015-02-10 Lars Ingebrigtsen <larsi@gnus.org> | ||
| 2 | |||
| 3 | * net/shr.el (shr-use-fonts): New variable. | ||
| 4 | (shr-fill-text): Rename from "fold". | ||
| 5 | (shr-pixel-column, shr-pixel-region, shr-string-pixel-width): New | ||
| 6 | functions. | ||
| 7 | (shr-insert): Just insert, don't fill the text. Filling is now | ||
| 8 | done afterwards per display unit. | ||
| 9 | (shr-fill-lines, shr-fill-line): New functions to fill text on a | ||
| 10 | per-unit base. | ||
| 11 | (shr-find-fill-point): Take a "beginning" parameter. | ||
| 12 | (shr-indent): Indent using the :width display parameter when using | ||
| 13 | fonts. | ||
| 14 | (shr-parse-style): Ignore "inherit" values, since we already do that. | ||
| 15 | (shr-tag-img): Remove the insertion states. | ||
| 16 | (shr-tag-blockquote): New-style filling. | ||
| 17 | (shr-tag-dd): Ditto. | ||
| 18 | (shr-tag-li): Ditto. | ||
| 19 | (shr-mark-fill): New function to mark lines that need filling. | ||
| 20 | (shr-tag-h1): Use a larger font. | ||
| 21 | (shr-tag-table-1): Get the natural and suggested widths in one | ||
| 22 | rendering. | ||
| 23 | (shr-tag-table): Create the "fixed" version of the table only once | ||
| 24 | so that we can cache data in the table. | ||
| 25 | (shr-insert-table): Get colspan calculations right by having | ||
| 26 | zero-width columns after colspan ones. | ||
| 27 | (shr-expand-alignments): New function to make :align-to specs work | ||
| 28 | right when rendered in one buffer and displayed in another one. | ||
| 29 | (shr-insert-table-ruler): Use :align-to to get the widths right. | ||
| 30 | (shr-make-table): Cache more. | ||
| 31 | (shr-make-table-1): Use the new <td> data layout. | ||
| 32 | (shr-pixel-buffer-width): New function. | ||
| 33 | (shr-render-td): Add a caching layer. | ||
| 34 | (shr-dom-max-natural-width): New function. | ||
| 35 | |||
| 1 | 2015-02-10 Fabián Ezequiel Gallina <fgallina@gnu.org> | 36 | 2015-02-10 Fabián Ezequiel Gallina <fgallina@gnu.org> |
| 2 | 37 | ||
| 3 | python.el: Improved shell font lock respecting markers. (Bug#19650) | 38 | python.el: Improved shell font lock respecting markers. (Bug#19650) |
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 32d3f08f586..ac7e2acab93 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2015-02-10 Lars Ingebrigtsen <larsi@gnus.org> | ||
| 2 | |||
| 3 | * mm-decode.el (mm-shr): Only pass the fill column when not using | ||
| 4 | fonts, because limiting the width to what's appropriate for followups | ||
| 5 | doesn't really help when not using proportional fonts. | ||
| 6 | |||
| 7 | 2015-02-09 Lars Ingebrigtsen <larsi@gnus.org> | ||
| 8 | |||
| 9 | * mm-decode.el (mm-convert-shr-links): Don't overwrite the faces from | ||
| 10 | shr, beacause that breaks folding. | ||
| 11 | (mm-shr): Don't shorten the width when using fonts. | ||
| 12 | |||
| 1 | 2015-02-05 Teodor Zlatanov <tzz@lifelogs.com> | 13 | 2015-02-05 Teodor Zlatanov <tzz@lifelogs.com> |
| 2 | 14 | ||
| 3 | * gnus-start.el (gnus-save-newsrc-file-check-timestamp): Remove | 15 | * gnus-start.el (gnus-save-newsrc-file-check-timestamp): Remove |
diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el index 311ea7cffff..6c783bbef03 100644 --- a/lisp/gnus/mm-decode.el +++ b/lisp/gnus/mm-decode.el | |||
| @@ -1815,6 +1815,7 @@ If RECURSIVE, search recursively." | |||
| 1815 | (start end &optional base-url)) | 1815 | (start end &optional base-url)) |
| 1816 | (declare-function shr-insert-document "shr" (dom)) | 1816 | (declare-function shr-insert-document "shr" (dom)) |
| 1817 | (defvar shr-blocked-images) | 1817 | (defvar shr-blocked-images) |
| 1818 | (defvar shr-use-fonts) | ||
| 1818 | (defvar gnus-inhibit-images) | 1819 | (defvar gnus-inhibit-images) |
| 1819 | (autoload 'gnus-blocked-images "gnus-art") | 1820 | (autoload 'gnus-blocked-images "gnus-art") |
| 1820 | 1821 | ||
| @@ -1822,7 +1823,10 @@ If RECURSIVE, search recursively." | |||
| 1822 | ;; Require since we bind its variables. | 1823 | ;; Require since we bind its variables. |
| 1823 | (require 'shr) | 1824 | (require 'shr) |
| 1824 | (let ((article-buffer (current-buffer)) | 1825 | (let ((article-buffer (current-buffer)) |
| 1825 | (shr-width fill-column) | 1826 | (shr-width (if (and (boundp 'shr-use-fonts) |
| 1827 | shr-use-fonts) | ||
| 1828 | nil | ||
| 1829 | fill-column)) | ||
| 1826 | (shr-content-function (lambda (id) | 1830 | (shr-content-function (lambda (id) |
| 1827 | (let ((handle (mm-get-content-id id))) | 1831 | (let ((handle (mm-get-content-id id))) |
| 1828 | (when handle | 1832 | (when handle |
| @@ -1890,12 +1894,15 @@ If RECURSIVE, search recursively." | |||
| 1890 | (< start (point-max))) | 1894 | (< start (point-max))) |
| 1891 | (when (setq start (text-property-not-all start (point-max) 'shr-url nil)) | 1895 | (when (setq start (text-property-not-all start (point-max) 'shr-url nil)) |
| 1892 | (setq end (next-single-property-change start 'shr-url nil (point-max))) | 1896 | (setq end (next-single-property-change start 'shr-url nil (point-max))) |
| 1897 | (setq face (get-text-property start 'face)) | ||
| 1893 | (widget-convert-button | 1898 | (widget-convert-button |
| 1894 | 'url-link start end | 1899 | 'url-link start end |
| 1895 | :help-echo (get-text-property start 'help-echo) | 1900 | :help-echo (get-text-property start 'help-echo) |
| 1896 | :keymap shr-map | 1901 | :keymap shr-map |
| 1897 | (get-text-property start 'shr-url)) | 1902 | (get-text-property start 'shr-url)) |
| 1898 | (put-text-property start end 'local-map nil) | 1903 | (put-text-property start end 'local-map nil) |
| 1904 | (dolist (overlay (overlays-at start)) | ||
| 1905 | (overlay-put overlay 'face nil)) | ||
| 1899 | (setq start end))))) | 1906 | (setq start end))))) |
| 1900 | 1907 | ||
| 1901 | (defun mm-handle-filename (handle) | 1908 | (defun mm-handle-filename (handle) |
diff --git a/lisp/net/eww.el b/lisp/net/eww.el index ec7a0baacf6..c401701f255 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el | |||
| @@ -409,7 +409,6 @@ See the `eww-search-prefix' variable for the search engine used." | |||
| 409 | (form . eww-tag-form) | 409 | (form . eww-tag-form) |
| 410 | (input . eww-tag-input) | 410 | (input . eww-tag-input) |
| 411 | (textarea . eww-tag-textarea) | 411 | (textarea . eww-tag-textarea) |
| 412 | (body . eww-tag-body) | ||
| 413 | (select . eww-tag-select) | 412 | (select . eww-tag-select) |
| 414 | (link . eww-tag-link) | 413 | (link . eww-tag-link) |
| 415 | (a . eww-tag-a)))) | 414 | (a . eww-tag-a)))) |
| @@ -495,15 +494,6 @@ See the `eww-search-prefix' variable for the search engine used." | |||
| 495 | (replace-regexp-in-string "[ \t\r\n]+" " " (dom-text dom)))) | 494 | (replace-regexp-in-string "[ \t\r\n]+" " " (dom-text dom)))) |
| 496 | (eww-update-header-line-format)) | 495 | (eww-update-header-line-format)) |
| 497 | 496 | ||
| 498 | (defun eww-tag-body (dom) | ||
| 499 | (let* ((start (point)) | ||
| 500 | (fgcolor (or (dom-attr dom 'fgcolor) (dom-attr dom 'text))) | ||
| 501 | (bgcolor (dom-attr dom 'bgcolor)) | ||
| 502 | (shr-stylesheet (list (cons 'color fgcolor) | ||
| 503 | (cons 'background-color bgcolor)))) | ||
| 504 | (shr-generic dom) | ||
| 505 | (shr-colorize-region start (point) fgcolor bgcolor))) | ||
| 506 | |||
| 507 | (defun eww-display-raw (buffer &optional encode) | 497 | (defun eww-display-raw (buffer &optional encode) |
| 508 | (let ((data (buffer-substring (point) (point-max)))) | 498 | (let ((data (buffer-substring (point) (point-max)))) |
| 509 | (unless (buffer-live-p buffer) | 499 | (unless (buffer-live-p buffer) |
| @@ -653,6 +643,7 @@ the like." | |||
| 653 | (define-key map "H" 'eww-list-histories) | 643 | (define-key map "H" 'eww-list-histories) |
| 654 | (define-key map "E" 'eww-set-character-encoding) | 644 | (define-key map "E" 'eww-set-character-encoding) |
| 655 | (define-key map "S" 'eww-list-buffers) | 645 | (define-key map "S" 'eww-list-buffers) |
| 646 | (define-key map "F" 'eww-toggle-fonts) | ||
| 656 | 647 | ||
| 657 | (define-key map "b" 'eww-add-bookmark) | 648 | (define-key map "b" 'eww-add-bookmark) |
| 658 | (define-key map "B" 'eww-list-bookmarks) | 649 | (define-key map "B" 'eww-list-bookmarks) |
| @@ -1425,6 +1416,15 @@ Differences in #targets are ignored." | |||
| 1425 | (eww-reload nil 'utf-8) | 1416 | (eww-reload nil 'utf-8) |
| 1426 | (eww-reload nil charset))) | 1417 | (eww-reload nil charset))) |
| 1427 | 1418 | ||
| 1419 | (defun eww-toggle-fonts () | ||
| 1420 | "Toggle whether to use monospaced or font-enabled layouts." | ||
| 1421 | (interactive) | ||
| 1422 | (message "Fonts are now %s" | ||
| 1423 | (if (setq shr-use-fonts (not shr-use-fonts)) | ||
| 1424 | "on" | ||
| 1425 | "off")) | ||
| 1426 | (eww-reload)) | ||
| 1427 | |||
| 1428 | ;;; Bookmarks code | 1428 | ;;; Bookmarks code |
| 1429 | 1429 | ||
| 1430 | (defvar eww-bookmarks nil) | 1430 | (defvar eww-bookmarks nil) |
diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 59c277b01c2..06a75a46bf2 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el | |||
| @@ -57,6 +57,12 @@ fit these criteria." | |||
| 57 | :group 'shr | 57 | :group 'shr |
| 58 | :type '(choice (const nil) regexp)) | 58 | :type '(choice (const nil) regexp)) |
| 59 | 59 | ||
| 60 | (defcustom shr-use-fonts nil | ||
| 61 | "If non-nil, use proportional fonts for text." | ||
| 62 | :version "25.1" | ||
| 63 | :group 'shr | ||
| 64 | :type 'boolean) | ||
| 65 | |||
| 60 | (defcustom shr-table-horizontal-line nil | 66 | (defcustom shr-table-horizontal-line nil |
| 61 | "Character used to draw horizontal table lines. | 67 | "Character used to draw horizontal table lines. |
| 62 | If nil, don't draw horizontal table lines." | 68 | If nil, don't draw horizontal table lines." |
| @@ -132,10 +138,9 @@ cid: URL as the argument.") | |||
| 132 | ;;; Internal variables. | 138 | ;;; Internal variables. |
| 133 | 139 | ||
| 134 | (defvar shr-folding-mode nil) | 140 | (defvar shr-folding-mode nil) |
| 135 | (defvar shr-state nil) | ||
| 136 | (defvar shr-start nil) | 141 | (defvar shr-start nil) |
| 137 | (defvar shr-indentation 0) | 142 | (defvar shr-indentation 0) |
| 138 | (defvar shr-internal-width (or shr-width (1- (window-width)))) | 143 | (defvar shr-internal-width nil) |
| 139 | (defvar shr-list-mode nil) | 144 | (defvar shr-list-mode nil) |
| 140 | (defvar shr-content-cache nil) | 145 | (defvar shr-content-cache nil) |
| 141 | (defvar shr-kinsoku-shorten nil) | 146 | (defvar shr-kinsoku-shorten nil) |
| @@ -149,6 +154,9 @@ cid: URL as the argument.") | |||
| 149 | (defvar shr-target-id nil) | 154 | (defvar shr-target-id nil) |
| 150 | (defvar shr-inhibit-decoration nil) | 155 | (defvar shr-inhibit-decoration nil) |
| 151 | (defvar shr-table-separator-length 1) | 156 | (defvar shr-table-separator-length 1) |
| 157 | (defvar shr-table-separator-pixel-width 0) | ||
| 158 | (defvar shr-table-id nil) | ||
| 159 | (defvar shr-current-font nil) | ||
| 152 | 160 | ||
| 153 | (defvar shr-map | 161 | (defvar shr-map |
| 154 | (let ((map (make-sparse-keymap))) | 162 | (let ((map (make-sparse-keymap))) |
| @@ -202,13 +210,22 @@ DOM should be a parse tree as generated by | |||
| 202 | `libxml-parse-html-region' or similar." | 210 | `libxml-parse-html-region' or similar." |
| 203 | (setq shr-content-cache nil) | 211 | (setq shr-content-cache nil) |
| 204 | (let ((start (point)) | 212 | (let ((start (point)) |
| 205 | (shr-state nil) | ||
| 206 | (shr-start nil) | 213 | (shr-start nil) |
| 207 | (shr-base nil) | 214 | (shr-base nil) |
| 208 | (shr-depth 0) | 215 | (shr-depth 0) |
| 216 | (shr-table-id 0) | ||
| 209 | (shr-warning nil) | 217 | (shr-warning nil) |
| 210 | (shr-internal-width (or shr-width (1- (window-width))))) | 218 | (shr-table-separator-pixel-width (shr-string-pixel-width "-")) |
| 219 | (shr-internal-width (or (and shr-width | ||
| 220 | (if (not shr-use-fonts) | ||
| 221 | shr-width | ||
| 222 | (* shr-width (frame-char-width)))) | ||
| 223 | (if (not shr-use-fonts) | ||
| 224 | (- (window-width) 2) | ||
| 225 | (- (window-pixel-width) | ||
| 226 | (* (frame-fringe-width) 2)))))) | ||
| 211 | (shr-descend dom) | 227 | (shr-descend dom) |
| 228 | (shr-fill-lines start (point)) | ||
| 212 | (shr-remove-trailing-whitespace start (point)) | 229 | (shr-remove-trailing-whitespace start (point)) |
| 213 | (when shr-warning | 230 | (when shr-warning |
| 214 | (message "%s" shr-warning)))) | 231 | (message "%s" shr-warning)))) |
| @@ -303,7 +320,7 @@ redirects somewhere else." | |||
| 303 | (let ((text (get-text-property (point) 'shr-alt))) | 320 | (let ((text (get-text-property (point) 'shr-alt))) |
| 304 | (if (not text) | 321 | (if (not text) |
| 305 | (message "No image under point") | 322 | (message "No image under point") |
| 306 | (message "%s" (shr-fold-text text))))) | 323 | (message "%s" (shr-fill-text text))))) |
| 307 | 324 | ||
| 308 | (defun shr-browse-image (&optional copy-url) | 325 | (defun shr-browse-image (&optional copy-url) |
| 309 | "Browse the image under point. | 326 | "Browse the image under point. |
| @@ -414,14 +431,14 @@ size, and full-buffer size." | |||
| 414 | (cdr (assq 'color shr-stylesheet)) | 431 | (cdr (assq 'color shr-stylesheet)) |
| 415 | (cdr (assq 'background-color shr-stylesheet)))))))) | 432 | (cdr (assq 'background-color shr-stylesheet)))))))) |
| 416 | 433 | ||
| 417 | (defun shr-fold-text (text) | 434 | (defun shr-fill-text (text) |
| 418 | (if (zerop (length text)) | 435 | (if (zerop (length text)) |
| 419 | text | 436 | text |
| 420 | (with-temp-buffer | 437 | (with-temp-buffer |
| 421 | (let ((shr-indentation 0) | 438 | (let ((shr-indentation 0) |
| 422 | (shr-state nil) | ||
| 423 | (shr-start nil) | 439 | (shr-start nil) |
| 424 | (shr-internal-width (window-width))) | 440 | (shr-internal-width (- (window-pixel-width) |
| 441 | (* (frame-fringe-width) 2)))) | ||
| 425 | (shr-insert text) | 442 | (shr-insert text) |
| 426 | (buffer-string))))) | 443 | (buffer-string))))) |
| 427 | 444 | ||
| @@ -447,76 +464,123 @@ size, and full-buffer size." | |||
| 447 | (unless (shr-char-kinsoku-bol-p (make-char 'japanese-jisx0208 33 35)) | 464 | (unless (shr-char-kinsoku-bol-p (make-char 'japanese-jisx0208 33 35)) |
| 448 | (load "kinsoku" nil t)) | 465 | (load "kinsoku" nil t)) |
| 449 | 466 | ||
| 467 | (defun shr-pixel-column () | ||
| 468 | (if (not shr-use-fonts) | ||
| 469 | (current-column) | ||
| 470 | (if (not (get-buffer-window (current-buffer))) | ||
| 471 | (save-window-excursion | ||
| 472 | (set-window-buffer nil (current-buffer)) | ||
| 473 | (car (window-text-pixel-size nil (line-beginning-position) (point)))) | ||
| 474 | (car (window-text-pixel-size nil (line-beginning-position) (point)))))) | ||
| 475 | |||
| 476 | (defun shr-pixel-region () | ||
| 477 | (- (shr-pixel-column) | ||
| 478 | (save-excursion | ||
| 479 | (goto-char (mark)) | ||
| 480 | (shr-pixel-column)))) | ||
| 481 | |||
| 482 | (defun shr-string-pixel-width (string) | ||
| 483 | (if (not shr-use-fonts) | ||
| 484 | (length string) | ||
| 485 | (with-temp-buffer | ||
| 486 | (insert string) | ||
| 487 | (shr-pixel-column)))) | ||
| 488 | |||
| 450 | (defun shr-insert (text) | 489 | (defun shr-insert (text) |
| 451 | (when (and (eq shr-state 'image) | 490 | (when (and (not (bolp)) |
| 452 | (not (bolp)) | 491 | (get-text-property (1- (point)) 'image-url)) |
| 453 | (not (string-match "\\`[ \t\n]+\\'" text))) | 492 | (insert "\n")) |
| 454 | (insert "\n") | ||
| 455 | (setq shr-state nil)) | ||
| 456 | (cond | 493 | (cond |
| 457 | ((eq shr-folding-mode 'none) | 494 | ((eq shr-folding-mode 'none) |
| 458 | (insert text)) | 495 | (insert text)) |
| 459 | (t | 496 | (t |
| 460 | (when (and (string-match "\\`[ \t\n ]" text) | 497 | (when (and (string-match "\\`[ \t\n\r ]" text) |
| 461 | (not (bolp)) | 498 | (not (bolp)) |
| 462 | (not (eq (char-after (1- (point))) ? ))) | 499 | (not (eq (char-after (1- (point))) ? ))) |
| 463 | (insert " ")) | 500 | (insert " ")) |
| 464 | (dolist (elem (split-string text "[ \f\t\n\r\v ]+" t)) | 501 | (let ((start (point)) |
| 465 | (when (and (bolp) | 502 | (bolp (bolp))) |
| 466 | (> shr-indentation 0)) | 503 | (insert text) |
| 467 | (shr-indent)) | 504 | (save-restriction |
| 468 | ;; No space is needed behind a wide character categorized as | 505 | (narrow-to-region start (point)) |
| 469 | ;; kinsoku-bol, between characters both categorized as nospace, | 506 | (goto-char start) |
| 470 | ;; or at the beginning of a line. | 507 | (when (looking-at "[ \t\n\r ]+") |
| 471 | (let (prev) | 508 | (replace-match "" t t)) |
| 472 | (when (and (> (current-column) shr-indentation) | 509 | (while (re-search-forward "[ \t\n\r ]+" nil t) |
| 473 | (eq (preceding-char) ? ) | 510 | (replace-match " " t t)) |
| 474 | (or (= (line-beginning-position) (1- (point))) | 511 | (goto-char (point-max))) |
| 475 | (and (shr-char-breakable-p | 512 | ;; We may have removed everything we inserted if if was just |
| 476 | (setq prev (char-after (- (point) 2)))) | 513 | ;; spaces. |
| 477 | (shr-char-kinsoku-bol-p prev)) | 514 | (unless (= start (point)) |
| 478 | (and (shr-char-nospace-p prev) | 515 | ;; Mark all lines that should possibly be folded afterwards. |
| 479 | (shr-char-nospace-p (aref elem 0))))) | 516 | (when bolp |
| 480 | (delete-char -1))) | 517 | (shr-mark-fill start)) |
| 481 | ;; The shr-start is a special variable that is used to pass | 518 | (when shr-use-fonts |
| 482 | ;; upwards the first point in the buffer where the text really | 519 | (add-face-text-property start (point) |
| 483 | ;; starts. | 520 | (or shr-current-font 'variable-pitch) |
| 484 | (unless shr-start | 521 | t))))))) |
| 485 | (setq shr-start (point))) | 522 | |
| 486 | (insert elem) | 523 | (defun shr-fill-lines (start end) |
| 487 | (setq shr-state nil) | 524 | (if (<= shr-internal-width 0) |
| 488 | (let (found) | 525 | nil |
| 489 | (while (and (> (current-column) shr-internal-width) | 526 | (save-restriction |
| 490 | (> shr-internal-width 0) | 527 | (narrow-to-region start end) |
| 491 | (progn | 528 | (goto-char start) |
| 492 | (setq found (shr-find-fill-point)) | 529 | (when (get-text-property (point) 'shr-indentation) |
| 493 | (not (eolp)))) | 530 | (shr-fill-line)) |
| 494 | (when (eq (preceding-char) ? ) | 531 | (while (setq start (next-single-property-change start 'shr-indentation)) |
| 495 | (delete-char -1)) | 532 | (goto-char start) |
| 496 | (insert "\n") | 533 | (when (bolp) |
| 497 | (unless found | 534 | (shr-fill-line))) |
| 498 | ;; No space is needed at the beginning of a line. | 535 | (goto-char (point-max))))) |
| 499 | (when (eq (following-char) ? ) | 536 | |
| 500 | (delete-char 1))) | 537 | (defun shr-vertical-motion (column) |
| 501 | (when (> shr-indentation 0) | 538 | (if (not shr-use-fonts) |
| 502 | (shr-indent)) | 539 | (move-to-column column) |
| 503 | (end-of-line)) | 540 | (unless (eolp) |
| 504 | (if (<= (current-column) shr-internal-width) | 541 | (forward-char 1)) |
| 505 | (insert " ") | 542 | (vertical-motion (cons (/ column (frame-char-width)) 0)) |
| 506 | ;; In case we couldn't get a valid break point (because of a | 543 | (unless (eolp) |
| 507 | ;; word that's longer than `shr-internal-width'), just break anyway. | 544 | (forward-char 1)))) |
| 508 | (insert "\n") | 545 | |
| 509 | (when (> shr-indentation 0) | 546 | (defun shr-fill-line () |
| 510 | (shr-indent))))) | 547 | (let ((shr-indentation (get-text-property (point) 'shr-indentation)) |
| 511 | (unless (string-match "[ \t\r\n ]\\'" text) | 548 | (continuation (get-text-property |
| 512 | (delete-char -1))))) | 549 | (point) 'shr-continuation-indentation)) |
| 513 | 550 | start) | |
| 514 | (defun shr-find-fill-point () | 551 | (put-text-property (point) (1+ (point)) 'shr-indentation nil) |
| 515 | (when (> (move-to-column shr-internal-width) shr-internal-width) | 552 | (shr-indent) |
| 516 | (backward-char 1)) | 553 | (setq start (point)) |
| 554 | (setq shr-indentation (or continuation shr-indentation)) | ||
| 555 | (shr-vertical-motion shr-internal-width) | ||
| 556 | (when (looking-at " $") | ||
| 557 | (delete-region (point) (line-end-position))) | ||
| 558 | (while (not (eolp)) | ||
| 559 | ;; We have to do some folding. First find the first | ||
| 560 | ;; previous point suitable for folding. | ||
| 561 | (if (or (not (shr-find-fill-point (line-beginning-position))) | ||
| 562 | (= (point) start)) | ||
| 563 | ;; We had unbreakable text (for this width), so just go to | ||
| 564 | ;; the first space and carry on. | ||
| 565 | (progn | ||
| 566 | (beginning-of-line) | ||
| 567 | (skip-chars-forward " ") | ||
| 568 | (search-forward " " (line-end-position) 'move))) | ||
| 569 | ;; Success; continue. | ||
| 570 | (when (= (preceding-char) ?\s) | ||
| 571 | (delete-char -1)) | ||
| 572 | (insert "\n") | ||
| 573 | (shr-indent) | ||
| 574 | (setq start (point)) | ||
| 575 | (shr-vertical-motion shr-internal-width) | ||
| 576 | (when (looking-at " $") | ||
| 577 | (delete-region (point) (line-end-position)))))) | ||
| 578 | |||
| 579 | (defun shr-find-fill-point (start) | ||
| 517 | (let ((bp (point)) | 580 | (let ((bp (point)) |
| 581 | (end (point)) | ||
| 518 | failed) | 582 | failed) |
| 519 | (while (not (or (setq failed (<= (current-column) shr-indentation)) | 583 | (while (not (or (setq failed (<= (point) start)) |
| 520 | (eq (preceding-char) ? ) | 584 | (eq (preceding-char) ? ) |
| 521 | (eq (following-char) ? ) | 585 | (eq (following-char) ? ) |
| 522 | (shr-char-breakable-p (preceding-char)) | 586 | (shr-char-breakable-p (preceding-char)) |
| @@ -547,12 +611,12 @@ size, and full-buffer size." | |||
| 547 | (while (and (not (memq (preceding-char) (list ?\C-@ ?\n ? ))) | 611 | (while (and (not (memq (preceding-char) (list ?\C-@ ?\n ? ))) |
| 548 | (shr-char-kinsoku-eol-p (preceding-char))) | 612 | (shr-char-kinsoku-eol-p (preceding-char))) |
| 549 | (backward-char 1)) | 613 | (backward-char 1)) |
| 550 | (when (setq failed (<= (current-column) shr-indentation)) | 614 | (when (setq failed (<= (point) start)) |
| 551 | ;; There's no breakable point that doesn't violate kinsoku, | 615 | ;; There's no breakable point that doesn't violate kinsoku, |
| 552 | ;; so we look for the second best position. | 616 | ;; so we look for the second best position. |
| 553 | (while (and (progn | 617 | (while (and (progn |
| 554 | (forward-char 1) | 618 | (forward-char 1) |
| 555 | (<= (current-column) shr-internal-width)) | 619 | (<= (point) end)) |
| 556 | (progn | 620 | (progn |
| 557 | (setq bp (point)) | 621 | (setq bp (point)) |
| 558 | (shr-char-kinsoku-eol-p (following-char))))) | 622 | (shr-char-kinsoku-eol-p (following-char))))) |
| @@ -567,7 +631,7 @@ size, and full-buffer size." | |||
| 567 | (not (memq (preceding-char) (list ?\C-@ ?\n ? ))) | 631 | (not (memq (preceding-char) (list ?\C-@ ?\n ? ))) |
| 568 | (or (shr-char-kinsoku-eol-p (preceding-char)) | 632 | (or (shr-char-kinsoku-eol-p (preceding-char)) |
| 569 | (shr-char-kinsoku-bol-p (following-char))))))) | 633 | (shr-char-kinsoku-bol-p (following-char))))))) |
| 570 | (when (setq failed (<= (current-column) shr-indentation)) | 634 | (when (setq failed (<= (point) start)) |
| 571 | ;; There's no breakable point that doesn't violate kinsoku, | 635 | ;; There's no breakable point that doesn't violate kinsoku, |
| 572 | ;; so we go to the second best position. | 636 | ;; so we go to the second best position. |
| 573 | (if (looking-at "\\(\\c<+\\)\\c<") | 637 | (if (looking-at "\\(\\c<+\\)\\c<") |
| @@ -664,13 +728,18 @@ size, and full-buffer size." | |||
| 664 | 728 | ||
| 665 | (defun shr-indent () | 729 | (defun shr-indent () |
| 666 | (when (> shr-indentation 0) | 730 | (when (> shr-indentation 0) |
| 667 | (insert (make-string shr-indentation ? )))) | 731 | (insert |
| 732 | (if (not shr-use-fonts) | ||
| 733 | (make-string shr-indentation ?\s) | ||
| 734 | (propertize " " | ||
| 735 | 'display | ||
| 736 | `(space :width (,shr-indentation))))))) | ||
| 668 | 737 | ||
| 669 | (defun shr-fontize-dom (dom &rest types) | 738 | (defun shr-fontize-dom (dom &rest types) |
| 670 | (let (shr-start) | 739 | (let ((start (point))) |
| 671 | (shr-generic dom) | 740 | (shr-generic dom) |
| 672 | (dolist (type types) | 741 | (dolist (type types) |
| 673 | (shr-add-font (or shr-start (point)) (point) type)))) | 742 | (shr-add-font start (point) type)))) |
| 674 | 743 | ||
| 675 | ;; Add face to the region, but avoid putting the font properties on | 744 | ;; Add face to the region, but avoid putting the font properties on |
| 676 | ;; blank text at the start of the line, and the newline at the end, to | 745 | ;; blank text at the start of the line, and the newline at the end, to |
| @@ -1070,13 +1139,11 @@ ones, in case fg and bg are nil." | |||
| 1070 | 1139 | ||
| 1071 | (defun shr-tag-p (dom) | 1140 | (defun shr-tag-p (dom) |
| 1072 | (shr-ensure-paragraph) | 1141 | (shr-ensure-paragraph) |
| 1073 | (shr-indent) | ||
| 1074 | (shr-generic dom) | 1142 | (shr-generic dom) |
| 1075 | (shr-ensure-paragraph)) | 1143 | (shr-ensure-paragraph)) |
| 1076 | 1144 | ||
| 1077 | (defun shr-tag-div (dom) | 1145 | (defun shr-tag-div (dom) |
| 1078 | (shr-ensure-newline) | 1146 | (shr-ensure-newline) |
| 1079 | (shr-indent) | ||
| 1080 | (shr-generic dom) | 1147 | (shr-generic dom) |
| 1081 | (shr-ensure-newline)) | 1148 | (shr-ensure-newline)) |
| 1082 | 1149 | ||
| @@ -1116,9 +1183,10 @@ ones, in case fg and bg are nil." | |||
| 1116 | (value (replace-regexp-in-string "^ +\\| +$" "" (cadr elem)))) | 1183 | (value (replace-regexp-in-string "^ +\\| +$" "" (cadr elem)))) |
| 1117 | (when (string-match " *!important\\'" value) | 1184 | (when (string-match " *!important\\'" value) |
| 1118 | (setq value (substring value 0 (match-beginning 0)))) | 1185 | (setq value (substring value 0 (match-beginning 0)))) |
| 1119 | (push (cons (intern name obarray) | 1186 | (unless (equal value "inherit") |
| 1120 | value) | 1187 | (push (cons (intern name obarray) |
| 1121 | plist))))) | 1188 | value) |
| 1189 | plist)))))) | ||
| 1122 | plist))) | 1190 | plist))) |
| 1123 | 1191 | ||
| 1124 | (defun shr-tag-base (dom) | 1192 | (defun shr-tag-base (dom) |
| @@ -1245,8 +1313,7 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1245 | (when (or url | 1313 | (when (or url |
| 1246 | (and dom | 1314 | (and dom |
| 1247 | (> (length (dom-attr dom 'src)) 0))) | 1315 | (> (length (dom-attr dom 'src)) 0))) |
| 1248 | (when (and (> (current-column) 0) | 1316 | (when (> (current-column) 0) |
| 1249 | (not (eq shr-state 'image))) | ||
| 1250 | (insert "\n")) | 1317 | (insert "\n")) |
| 1251 | (let ((alt (dom-attr dom 'alt)) | 1318 | (let ((alt (dom-attr dom 'alt)) |
| 1252 | (url (shr-expand-url (or url (dom-attr dom 'src))))) | 1319 | (url (shr-expand-url (or url (dom-attr dom 'src))))) |
| @@ -1276,10 +1343,9 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1276 | (and shr-blocked-images | 1343 | (and shr-blocked-images |
| 1277 | (string-match shr-blocked-images url))) | 1344 | (string-match shr-blocked-images url))) |
| 1278 | (setq shr-start (point)) | 1345 | (setq shr-start (point)) |
| 1279 | (let ((shr-state 'space)) | 1346 | (if (> (string-width alt) 8) |
| 1280 | (if (> (string-width alt) 8) | 1347 | (shr-insert (truncate-string-to-width alt 8)) |
| 1281 | (shr-insert (truncate-string-to-width alt 8)) | 1348 | (shr-insert alt))) |
| 1282 | (shr-insert alt)))) | ||
| 1283 | ((and (not shr-ignore-cache) | 1349 | ((and (not shr-ignore-cache) |
| 1284 | (url-is-cached (shr-encode-url url))) | 1350 | (url-is-cached (shr-encode-url url))) |
| 1285 | (funcall shr-put-image-function (shr-get-image-data url) alt)) | 1351 | (funcall shr-put-image-function (shr-get-image-data url) alt)) |
| @@ -1301,22 +1367,24 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1301 | (put-text-property start (point) 'image-displayer | 1367 | (put-text-property start (point) 'image-displayer |
| 1302 | (shr-image-displayer shr-content-function)) | 1368 | (shr-image-displayer shr-content-function)) |
| 1303 | (put-text-property start (point) 'help-echo | 1369 | (put-text-property start (point) 'help-echo |
| 1304 | (shr-fold-text (or (dom-attr dom 'title) alt)))) | 1370 | (shr-fill-text |
| 1305 | (setq shr-state 'image))))) | 1371 | (or (dom-attr dom 'title) alt)))))))) |
| 1306 | 1372 | ||
| 1307 | (defun shr-tag-pre (dom) | 1373 | (defun shr-tag-pre (dom) |
| 1308 | (let ((shr-folding-mode 'none)) | 1374 | (let ((shr-folding-mode 'none) |
| 1375 | (shr-current-font 'default)) | ||
| 1309 | (shr-ensure-newline) | 1376 | (shr-ensure-newline) |
| 1310 | (shr-indent) | ||
| 1311 | (shr-generic dom) | 1377 | (shr-generic dom) |
| 1312 | (shr-ensure-newline))) | 1378 | (shr-ensure-newline))) |
| 1313 | 1379 | ||
| 1314 | (defun shr-tag-blockquote (dom) | 1380 | (defun shr-tag-blockquote (dom) |
| 1315 | (shr-ensure-paragraph) | 1381 | (shr-ensure-paragraph) |
| 1316 | (shr-indent) | 1382 | (let ((start (point)) |
| 1317 | (let ((shr-indentation (+ shr-indentation 4))) | 1383 | (shr-indentation (+ shr-indentation |
| 1318 | (shr-generic dom)) | 1384 | (* 4 shr-table-separator-pixel-width)))) |
| 1319 | (shr-ensure-paragraph)) | 1385 | (shr-generic dom) |
| 1386 | (shr-ensure-paragraph) | ||
| 1387 | (shr-mark-fill start))) | ||
| 1320 | 1388 | ||
| 1321 | (defun shr-tag-dl (dom) | 1389 | (defun shr-tag-dl (dom) |
| 1322 | (shr-ensure-paragraph) | 1390 | (shr-ensure-paragraph) |
| @@ -1330,7 +1398,8 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1330 | 1398 | ||
| 1331 | (defun shr-tag-dd (dom) | 1399 | (defun shr-tag-dd (dom) |
| 1332 | (shr-ensure-newline) | 1400 | (shr-ensure-newline) |
| 1333 | (let ((shr-indentation (+ shr-indentation 4))) | 1401 | (let ((shr-indentation (+ shr-indentation |
| 1402 | (* 4 shr-table-separator-pixel-width)))) | ||
| 1334 | (shr-generic dom))) | 1403 | (shr-generic dom))) |
| 1335 | 1404 | ||
| 1336 | (defun shr-tag-ul (dom) | 1405 | (defun shr-tag-ul (dom) |
| @@ -1347,16 +1416,26 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1347 | 1416 | ||
| 1348 | (defun shr-tag-li (dom) | 1417 | (defun shr-tag-li (dom) |
| 1349 | (shr-ensure-newline) | 1418 | (shr-ensure-newline) |
| 1350 | (shr-indent) | 1419 | (let ((start (point))) |
| 1351 | (let* ((bullet | 1420 | (let* ((bullet |
| 1352 | (if (numberp shr-list-mode) | 1421 | (if (numberp shr-list-mode) |
| 1353 | (prog1 | 1422 | (prog1 |
| 1354 | (format "%d " shr-list-mode) | 1423 | (format "%d " shr-list-mode) |
| 1355 | (setq shr-list-mode (1+ shr-list-mode))) | 1424 | (setq shr-list-mode (1+ shr-list-mode))) |
| 1356 | shr-bullet)) | 1425 | shr-bullet))) |
| 1357 | (shr-indentation (+ shr-indentation (length bullet)))) | 1426 | (insert bullet) |
| 1358 | (insert bullet) | 1427 | (shr-mark-fill start) |
| 1359 | (shr-generic dom))) | 1428 | (let ((shr-indentation (+ shr-indentation |
| 1429 | (shr-string-pixel-width bullet)))) | ||
| 1430 | (put-text-property start (1+ start) | ||
| 1431 | 'shr-continuation-indentation shr-indentation) | ||
| 1432 | (shr-generic dom))))) | ||
| 1433 | |||
| 1434 | (defun shr-mark-fill (start) | ||
| 1435 | ;; We may not have inserted any text to fill. | ||
| 1436 | (unless (= start (point)) | ||
| 1437 | (put-text-property start (1+ start) | ||
| 1438 | 'shr-indentation shr-indentation))) | ||
| 1360 | 1439 | ||
| 1361 | (defun shr-tag-br (dom) | 1440 | (defun shr-tag-br (dom) |
| 1362 | (when (and (not (bobp)) | 1441 | (when (and (not (bobp)) |
| @@ -1365,15 +1444,14 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1365 | (or (not (bolp)) | 1444 | (or (not (bolp)) |
| 1366 | (and (> (- (point) 2) (point-min)) | 1445 | (and (> (- (point) 2) (point-min)) |
| 1367 | (not (= (char-after (- (point) 2)) ?\n))))) | 1446 | (not (= (char-after (- (point) 2)) ?\n))))) |
| 1368 | (insert "\n") | 1447 | (insert "\n")) |
| 1369 | (shr-indent)) | ||
| 1370 | (shr-generic dom)) | 1448 | (shr-generic dom)) |
| 1371 | 1449 | ||
| 1372 | (defun shr-tag-span (dom) | 1450 | (defun shr-tag-span (dom) |
| 1373 | (shr-generic dom)) | 1451 | (shr-generic dom)) |
| 1374 | 1452 | ||
| 1375 | (defun shr-tag-h1 (dom) | 1453 | (defun shr-tag-h1 (dom) |
| 1376 | (shr-heading dom 'bold 'underline)) | 1454 | (shr-heading dom '(variable-pitch (:height 1.3 :weight bold)))) |
| 1377 | 1455 | ||
| 1378 | (defun shr-tag-h2 (dom) | 1456 | (defun shr-tag-h2 (dom) |
| 1379 | (shr-heading dom 'bold)) | 1457 | (shr-heading dom 'bold)) |
| @@ -1392,7 +1470,8 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1392 | 1470 | ||
| 1393 | (defun shr-tag-hr (_dom) | 1471 | (defun shr-tag-hr (_dom) |
| 1394 | (shr-ensure-newline) | 1472 | (shr-ensure-newline) |
| 1395 | (insert (make-string shr-internal-width shr-hr-line) "\n")) | 1473 | ;; FIXME: Should try to make a line of the required pixel size. |
| 1474 | (insert (make-string (window-width) shr-hr-line) "\n")) | ||
| 1396 | 1475 | ||
| 1397 | (defun shr-tag-title (dom) | 1476 | (defun shr-tag-title (dom) |
| 1398 | (shr-heading dom 'bold 'underline)) | 1477 | (shr-heading dom 'bold 'underline)) |
| @@ -1424,20 +1503,23 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1424 | (shr-kinsoku-shorten t) | 1503 | (shr-kinsoku-shorten t) |
| 1425 | ;; Find all suggested widths. | 1504 | ;; Find all suggested widths. |
| 1426 | (columns (shr-column-specs dom)) | 1505 | (columns (shr-column-specs dom)) |
| 1427 | ;; Compute how many characters wide each TD should be. | 1506 | ;; Compute how many pixels wide each TD should be. |
| 1428 | (suggested-widths (shr-pro-rate-columns columns)) | 1507 | (suggested-widths (shr-pro-rate-columns columns)) |
| 1429 | ;; Do a "test rendering" to see how big each TD is (this can | 1508 | ;; Do a "test rendering" to see how big each TD is (this can |
| 1430 | ;; be smaller (if there's little text) or bigger (if there's | 1509 | ;; be smaller (if there's little text) or bigger (if there's |
| 1431 | ;; unbreakable text). | 1510 | ;; unbreakable text). |
| 1432 | (sketch (shr-make-table dom suggested-widths)) | 1511 | (elems (or (dom-attr dom 'shr-suggested-widths) |
| 1433 | ;; Compute the "natural" width by setting each column to 500 | 1512 | (shr-make-table dom suggested-widths nil |
| 1434 | ;; characters and see how wide they really render. | 1513 | 'shr-suggested-widths))) |
| 1435 | (natural (shr-make-table dom (make-vector (length columns) 500))) | 1514 | (sketch (loop for line in elems |
| 1515 | collect (mapcar #'car line))) | ||
| 1516 | (natural (loop for line in elems | ||
| 1517 | collect (mapcar #'cdr line))) | ||
| 1436 | (sketch-widths (shr-table-widths sketch natural suggested-widths))) | 1518 | (sketch-widths (shr-table-widths sketch natural suggested-widths))) |
| 1437 | ;; This probably won't work very well. | 1519 | ;; This probably won't work very well. |
| 1438 | (when (> (+ (loop for width across sketch-widths | 1520 | (when (> (+ (loop for width across sketch-widths |
| 1439 | summing (1+ width)) | 1521 | summing (1+ width)) |
| 1440 | shr-indentation 1) | 1522 | shr-indentation shr-table-separator-pixel-width) |
| 1441 | (frame-width)) | 1523 | (frame-width)) |
| 1442 | (setq truncate-lines t)) | 1524 | (setq truncate-lines t)) |
| 1443 | ;; Then render the table again with these new "hard" widths. | 1525 | ;; Then render the table again with these new "hard" widths. |
| @@ -1466,64 +1548,71 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1466 | ;; Try to output it anyway. | 1548 | ;; Try to output it anyway. |
| 1467 | (shr-generic dom) | 1549 | (shr-generic dom) |
| 1468 | ;; It's a real table, so render it. | 1550 | ;; It's a real table, so render it. |
| 1469 | (shr-tag-table-1 | 1551 | (if (dom-attr dom 'shr-fixed-table) |
| 1470 | (nconc | 1552 | (shr-tag-table-1 dom) |
| 1471 | (list 'table nil) | 1553 | ;; Only fix up the table once. |
| 1472 | (if caption `((tr nil (td nil ,@caption)))) | 1554 | (let ((table |
| 1473 | (cond (header | 1555 | (nconc |
| 1474 | (if footer | 1556 | (list 'table nil) |
| 1475 | ;; header + body + footer | 1557 | (if caption `((tr nil (td nil ,@caption)))) |
| 1476 | (if (= nheader nbody) | 1558 | (cond |
| 1477 | (if (= nbody nfooter) | 1559 | (header |
| 1478 | `((tr nil (td nil (table nil | 1560 | (if footer |
| 1479 | (tbody nil ,@header | 1561 | ;; header + body + footer |
| 1480 | ,@body ,@footer))))) | 1562 | (if (= nheader nbody) |
| 1481 | (nconc `((tr nil (td nil (table nil | 1563 | (if (= nbody nfooter) |
| 1482 | (tbody nil ,@header | 1564 | `((tr nil (td nil (table nil |
| 1483 | ,@body))))) | 1565 | (tbody nil ,@header |
| 1484 | (if (= nfooter 1) | 1566 | ,@body ,@footer))))) |
| 1485 | footer | 1567 | (nconc `((tr nil (td nil (table nil |
| 1486 | `((tr nil (td nil (table | 1568 | (tbody nil ,@header |
| 1487 | nil (tbody | ||
| 1488 | nil ,@footer)))))))) | ||
| 1489 | (nconc `((tr nil (td nil (table nil (tbody | ||
| 1490 | nil ,@header))))) | ||
| 1491 | (if (= nbody nfooter) | ||
| 1492 | `((tr nil (td nil (table | ||
| 1493 | nil (tbody nil ,@body | ||
| 1494 | ,@footer))))) | ||
| 1495 | (nconc `((tr nil (td nil (table | ||
| 1496 | nil (tbody nil | ||
| 1497 | ,@body))))) | 1569 | ,@body))))) |
| 1498 | (if (= nfooter 1) | 1570 | (if (= nfooter 1) |
| 1499 | footer | 1571 | footer |
| 1500 | `((tr nil (td nil (table | 1572 | `((tr nil (td nil (table |
| 1501 | nil | 1573 | nil (tbody |
| 1502 | (tbody | 1574 | nil ,@footer)))))))) |
| 1503 | nil | 1575 | (nconc `((tr nil (td nil (table nil (tbody |
| 1504 | ,@footer)))))))))) | 1576 | nil ,@header))))) |
| 1505 | ;; header + body | 1577 | (if (= nbody nfooter) |
| 1506 | (if (= nheader nbody) | 1578 | `((tr nil (td nil (table |
| 1507 | `((tr nil (td nil (table nil (tbody nil ,@header | 1579 | nil (tbody nil ,@body |
| 1508 | ,@body))))) | 1580 | ,@footer))))) |
| 1509 | (if (= nheader 1) | 1581 | (nconc `((tr nil (td nil (table |
| 1510 | `(,@header (tr nil (td nil (table | 1582 | nil (tbody nil |
| 1511 | nil (tbody nil ,@body))))) | 1583 | ,@body))))) |
| 1512 | `((tr nil (td nil (table nil (tbody nil ,@header)))) | 1584 | (if (= nfooter 1) |
| 1513 | (tr nil (td nil (table nil (tbody nil ,@body))))))))) | 1585 | footer |
| 1514 | (footer | 1586 | `((tr nil (td nil (table |
| 1515 | ;; body + footer | 1587 | nil |
| 1516 | (if (= nbody nfooter) | 1588 | (tbody |
| 1517 | `((tr nil (td nil (table | 1589 | nil |
| 1518 | nil (tbody nil ,@body ,@footer))))) | 1590 | ,@footer)))))))))) |
| 1519 | (nconc `((tr nil (td nil (table nil (tbody nil ,@body))))) | 1591 | ;; header + body |
| 1520 | (if (= nfooter 1) | 1592 | (if (= nheader nbody) |
| 1521 | footer | 1593 | `((tr nil (td nil (table nil (tbody nil ,@header |
| 1522 | `((tr nil (td nil (table | 1594 | ,@body))))) |
| 1523 | nil (tbody nil ,@footer))))))))) | 1595 | (if (= nheader 1) |
| 1524 | (caption | 1596 | `(,@header (tr nil (td nil (table |
| 1525 | `((tr nil (td nil (table nil (tbody nil ,@body)))))) | 1597 | nil (tbody nil ,@body))))) |
| 1526 | (body))))) | 1598 | `((tr nil (td nil (table nil (tbody nil ,@header)))) |
| 1599 | (tr nil (td nil (table nil (tbody nil ,@body))))))))) | ||
| 1600 | (footer | ||
| 1601 | ;; body + footer | ||
| 1602 | (if (= nbody nfooter) | ||
| 1603 | `((tr nil (td nil (table | ||
| 1604 | nil (tbody nil ,@body ,@footer))))) | ||
| 1605 | (nconc `((tr nil (td nil (table nil (tbody nil ,@body))))) | ||
| 1606 | (if (= nfooter 1) | ||
| 1607 | footer | ||
| 1608 | `((tr nil (td nil (table | ||
| 1609 | nil (tbody nil ,@footer))))))))) | ||
| 1610 | (caption | ||
| 1611 | `((tr nil (td nil (table nil (tbody nil ,@body)))))) | ||
| 1612 | (body))))) | ||
| 1613 | (dom-set-attribute table 'shr-fixed-table t) | ||
| 1614 | (setcdr dom (cdr table)) | ||
| 1615 | (shr-tag-table-1 dom)))) | ||
| 1527 | (when bgcolor | 1616 | (when bgcolor |
| 1528 | (shr-colorize-region start (point) (cdr (assq 'color shr-stylesheet)) | 1617 | (shr-colorize-region start (point) (cdr (assq 'color shr-stylesheet)) |
| 1529 | bgcolor)) | 1618 | bgcolor)) |
| @@ -1531,6 +1620,8 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1531 | ;; model isn't strong enough to allow us to put the images actually | 1620 | ;; model isn't strong enough to allow us to put the images actually |
| 1532 | ;; into the tables. | 1621 | ;; into the tables. |
| 1533 | (when (zerop shr-table-depth) | 1622 | (when (zerop shr-table-depth) |
| 1623 | (save-excursion | ||
| 1624 | (shr-expand-alignments start (point))) | ||
| 1534 | (dolist (elem (dom-by-tag dom 'object)) | 1625 | (dolist (elem (dom-by-tag dom 'object)) |
| 1535 | (shr-tag-object elem)) | 1626 | (shr-tag-object elem)) |
| 1536 | (dolist (elem (dom-by-tag dom 'img)) | 1627 | (dolist (elem (dom-by-tag dom 'img)) |
| @@ -1540,38 +1631,87 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1540 | (let* ((collapse (equal (cdr (assq 'border-collapse shr-stylesheet)) | 1631 | (let* ((collapse (equal (cdr (assq 'border-collapse shr-stylesheet)) |
| 1541 | "collapse")) | 1632 | "collapse")) |
| 1542 | (shr-table-separator-length (if collapse 0 1)) | 1633 | (shr-table-separator-length (if collapse 0 1)) |
| 1543 | (shr-table-vertical-line (if collapse "" shr-table-vertical-line))) | 1634 | (shr-table-vertical-line (if collapse "" shr-table-vertical-line)) |
| 1635 | (start (point))) | ||
| 1636 | (setq shr-table-id (1+ shr-table-id)) | ||
| 1544 | (unless collapse | 1637 | (unless collapse |
| 1545 | (shr-insert-table-ruler widths)) | 1638 | (shr-insert-table-ruler widths)) |
| 1546 | (dolist (row table) | 1639 | (dolist (row table) |
| 1547 | (let ((start (point)) | 1640 | (let ((start (point)) |
| 1641 | (align 0) | ||
| 1642 | (column-number 0) | ||
| 1548 | (height (let ((max 0)) | 1643 | (height (let ((max 0)) |
| 1549 | (dolist (column row) | 1644 | (dolist (column row) |
| 1550 | (setq max (max max (cadr column)))) | 1645 | (setq max (max max (nth 2 column)))) |
| 1551 | max))) | 1646 | max))) |
| 1552 | (dotimes (i height) | 1647 | (dotimes (i (max height 1)) |
| 1553 | (shr-indent) | 1648 | (shr-indent) |
| 1554 | (insert shr-table-vertical-line "\n")) | 1649 | (insert shr-table-vertical-line "\n")) |
| 1555 | (dolist (column row) | 1650 | (dolist (column row) |
| 1556 | (goto-char start) | 1651 | (when (> (nth 2 column) -1) |
| 1557 | (let ((lines (nth 2 column))) | 1652 | (goto-char start) |
| 1558 | (dolist (line lines) | 1653 | ;; Sum up all the widths from the column. (There may be |
| 1559 | (end-of-line) | 1654 | ;; more than one if this is a "colspan" column.) |
| 1560 | (insert line shr-table-vertical-line) | 1655 | (dotimes (i (nth 4 column)) |
| 1561 | (forward-line 1)) | 1656 | ;; The colspan directive may be wrong and there may not be |
| 1562 | ;; Add blank lines at padding at the bottom of the TD, | 1657 | ;; that number of columns. |
| 1563 | ;; possibly. | 1658 | (when (<= column-number (1- (length widths))) |
| 1564 | (dotimes (i (- height (length lines))) | 1659 | (setq align (+ align |
| 1565 | (end-of-line) | 1660 | (aref widths column-number) |
| 1566 | (let ((start (point))) | 1661 | (* 2 shr-table-separator-pixel-width)))) |
| 1567 | (insert (make-string (string-width (car lines)) ? ) | 1662 | (setq column-number (1+ column-number))) |
| 1568 | shr-table-vertical-line) | 1663 | (let ((lines (nth 3 column)) |
| 1569 | (when (nth 4 column) | 1664 | (pixel-align (if (not shr-use-fonts) |
| 1570 | (shr-add-font start (1- (point)) | 1665 | (* align (frame-char-width)) |
| 1571 | (list :background (nth 4 column))))) | 1666 | align))) |
| 1572 | (forward-line 1))))) | 1667 | (dolist (line lines) |
| 1668 | (end-of-line) | ||
| 1669 | (let ((start (point))) | ||
| 1670 | (insert line | ||
| 1671 | (propertize " " | ||
| 1672 | 'display `(space :align-to (,pixel-align)) | ||
| 1673 | 'shr-table-indent shr-table-id) | ||
| 1674 | shr-table-vertical-line) | ||
| 1675 | (shr-colorize-region | ||
| 1676 | start (1- (point)) (nth 5 column) (nth 6 column))) | ||
| 1677 | (forward-line 1)) | ||
| 1678 | ;; Add blank lines at padding at the bottom of the TD, | ||
| 1679 | ;; possibly. | ||
| 1680 | (dotimes (i (- height (length lines))) | ||
| 1681 | (end-of-line) | ||
| 1682 | (let ((start (point))) | ||
| 1683 | (insert (propertize " " | ||
| 1684 | 'display `(space :align-to (,pixel-align)) | ||
| 1685 | 'shr-table-indent shr-table-id) | ||
| 1686 | shr-table-vertical-line) | ||
| 1687 | (shr-colorize-region | ||
| 1688 | start (1- (point)) (nth 5 column) (nth 6 column))) | ||
| 1689 | (forward-line 1)))))) | ||
| 1573 | (unless collapse | 1690 | (unless collapse |
| 1574 | (shr-insert-table-ruler widths))))) | 1691 | (shr-insert-table-ruler widths))) |
| 1692 | (unless (= start (point)) | ||
| 1693 | (put-text-property start (1+ start) 'shr-table-id shr-table-id)))) | ||
| 1694 | |||
| 1695 | (defun shr-expand-alignments (start end) | ||
| 1696 | (while (< (setq start (next-single-property-change | ||
| 1697 | start 'shr-table-id nil end)) | ||
| 1698 | end) | ||
| 1699 | (goto-char start) | ||
| 1700 | (let* ((shr-use-fonts t) | ||
| 1701 | (id (get-text-property (point) 'shr-table-id)) | ||
| 1702 | (base (shr-pixel-column)) | ||
| 1703 | elem) | ||
| 1704 | (when id | ||
| 1705 | (save-excursion | ||
| 1706 | (while (setq elem (text-property-any | ||
| 1707 | (point) end 'shr-table-indent id)) | ||
| 1708 | (goto-char elem) | ||
| 1709 | (let ((align (get-text-property (point) 'display))) | ||
| 1710 | (put-text-property (point) (1+ (point)) 'display | ||
| 1711 | `(space :align-to (,(+ (car (nth 2 align)) | ||
| 1712 | base))))) | ||
| 1713 | (forward-char 1))))) | ||
| 1714 | (setq start (1+ start)))) | ||
| 1575 | 1715 | ||
| 1576 | (defun shr-insert-table-ruler (widths) | 1716 | (defun shr-insert-table-ruler (widths) |
| 1577 | (when shr-table-horizontal-line | 1717 | (when shr-table-horizontal-line |
| @@ -1579,9 +1719,17 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1579 | (> shr-indentation 0)) | 1719 | (> shr-indentation 0)) |
| 1580 | (shr-indent)) | 1720 | (shr-indent)) |
| 1581 | (insert shr-table-corner) | 1721 | (insert shr-table-corner) |
| 1582 | (dotimes (i (length widths)) | 1722 | (let ((total-width 0)) |
| 1583 | (insert (make-string (aref widths i) shr-table-horizontal-line) | 1723 | (dotimes (i (length widths)) |
| 1584 | shr-table-corner)) | 1724 | (setq total-width (+ total-width (aref widths i) |
| 1725 | (* shr-table-separator-pixel-width 2))) | ||
| 1726 | (insert (make-string (1+ (/ (aref widths i) | ||
| 1727 | shr-table-separator-pixel-width)) | ||
| 1728 | shr-table-horizontal-line) | ||
| 1729 | (propertize " " | ||
| 1730 | 'display `(space :align-to (,total-width)) | ||
| 1731 | 'shr-table-indent shr-table-id) | ||
| 1732 | shr-table-corner))) | ||
| 1585 | (insert "\n"))) | 1733 | (insert "\n"))) |
| 1586 | 1734 | ||
| 1587 | (defun shr-table-widths (table natural-table suggested-widths) | 1735 | (defun shr-table-widths (table natural-table suggested-widths) |
| @@ -1599,7 +1747,8 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1599 | (aset natural-widths i (max (aref natural-widths i) column)) | 1747 | (aset natural-widths i (max (aref natural-widths i) column)) |
| 1600 | (setq i (1+ i))))) | 1748 | (setq i (1+ i))))) |
| 1601 | (let ((extra (- (apply '+ (append suggested-widths nil)) | 1749 | (let ((extra (- (apply '+ (append suggested-widths nil)) |
| 1602 | (apply '+ (append widths nil)))) | 1750 | (apply '+ (append widths nil)) |
| 1751 | (* shr-table-separator-pixel-width (length widths)))) | ||
| 1603 | (expanded-columns 0)) | 1752 | (expanded-columns 0)) |
| 1604 | ;; We have extra, unused space, so divide this space amongst the | 1753 | ;; We have extra, unused space, so divide this space amongst the |
| 1605 | ;; columns. | 1754 | ;; columns. |
| @@ -1617,11 +1766,13 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1617 | (aref widths i)))))))) | 1766 | (aref widths i)))))))) |
| 1618 | widths)) | 1767 | widths)) |
| 1619 | 1768 | ||
| 1620 | (defun shr-make-table (dom widths &optional fill) | 1769 | (defun shr-make-table (dom widths &optional fill storage-attribute) |
| 1621 | (or (cadr (assoc (list dom widths fill) shr-content-cache)) | 1770 | (or (cadr (assoc (list dom widths fill) shr-content-cache)) |
| 1622 | (let ((data (shr-make-table-1 dom widths fill))) | 1771 | (let ((data (shr-make-table-1 dom widths fill))) |
| 1623 | (push (list (list dom widths fill) data) | 1772 | (push (list (list dom widths fill) data) |
| 1624 | shr-content-cache) | 1773 | shr-content-cache) |
| 1774 | (when storage-attribute | ||
| 1775 | (dom-set-attribute dom storage-attribute data)) | ||
| 1625 | data))) | 1776 | data))) |
| 1626 | 1777 | ||
| 1627 | (defun shr-make-table-1 (dom widths &optional fill) | 1778 | (defun shr-make-table-1 (dom widths &optional fill) |
| @@ -1634,7 +1785,7 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1634 | (dolist (row (dom-non-text-children dom)) | 1785 | (dolist (row (dom-non-text-children dom)) |
| 1635 | (when (eq (dom-tag row) 'tr) | 1786 | (when (eq (dom-tag row) 'tr) |
| 1636 | (let ((tds nil) | 1787 | (let ((tds nil) |
| 1637 | (columns (dom-children row)) | 1788 | (columns (dom-non-text-children row)) |
| 1638 | (i 0) | 1789 | (i 0) |
| 1639 | (width-column 0) | 1790 | (width-column 0) |
| 1640 | column) | 1791 | column) |
| @@ -1660,7 +1811,7 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1660 | (setq width | 1811 | (setq width |
| 1661 | (if column | 1812 | (if column |
| 1662 | (aref widths width-column) | 1813 | (aref widths width-column) |
| 1663 | 10)) | 1814 | (* 10 shr-table-separator-pixel-width))) |
| 1664 | (when (setq colspan (dom-attr column 'colspan)) | 1815 | (when (setq colspan (dom-attr column 'colspan)) |
| 1665 | (setq colspan (min (string-to-number colspan) | 1816 | (setq colspan (min (string-to-number colspan) |
| 1666 | ;; The colspan may be wrong, so | 1817 | ;; The colspan may be wrong, so |
| @@ -1682,35 +1833,80 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1682 | (setq width-column (+ width-column (1- colspan)) | 1833 | (setq width-column (+ width-column (1- colspan)) |
| 1683 | colspan-count colspan | 1834 | colspan-count colspan |
| 1684 | colspan-remaining colspan)) | 1835 | colspan-remaining colspan)) |
| 1685 | (when (or column | 1836 | (when column |
| 1686 | (not fill)) | ||
| 1687 | (let ((data (shr-render-td column width fill))) | 1837 | (let ((data (shr-render-td column width fill))) |
| 1688 | (if (and (not fill) | 1838 | (if (and (not fill) |
| 1689 | (> colspan-remaining 0)) | 1839 | (> colspan-remaining 0)) |
| 1690 | (progn | 1840 | (progn |
| 1691 | (when (= colspan-count colspan-remaining) | 1841 | (setq colspan-width (car data)) |
| 1692 | (setq colspan-width data)) | ||
| 1693 | (let ((this-width (/ colspan-width colspan-count))) | 1842 | (let ((this-width (/ colspan-width colspan-count))) |
| 1694 | (push this-width tds) | 1843 | (push (cons this-width (cadr data)) tds) |
| 1695 | (setq colspan-remaining (1- colspan-remaining)))) | 1844 | (setq colspan-remaining (1- colspan-remaining)))) |
| 1696 | (push data tds)))) | 1845 | (if (not fill) |
| 1846 | (push (cons (car data) (cadr data)) tds) | ||
| 1847 | (push data tds))))) | ||
| 1848 | (when (and colspan | ||
| 1849 | (> colspan 1)) | ||
| 1850 | (dotimes (c (1- colspan)) | ||
| 1851 | (setq i (1+ i)) | ||
| 1852 | (push | ||
| 1853 | (if fill | ||
| 1854 | (list 0 0 -1 nil 1 nil nil) | ||
| 1855 | '(0 . 0)) | ||
| 1856 | tds))) | ||
| 1697 | (setq i (1+ i) | 1857 | (setq i (1+ i) |
| 1698 | width-column (1+ width-column)))) | 1858 | width-column (1+ width-column)))) |
| 1699 | (push (nreverse tds) trs)))) | 1859 | (push (nreverse tds) trs)))) |
| 1700 | (nreverse trs))) | 1860 | (nreverse trs))) |
| 1701 | 1861 | ||
| 1862 | (defun shr-pixel-buffer-width () | ||
| 1863 | (if (not shr-use-fonts) | ||
| 1864 | (save-excursion | ||
| 1865 | (goto-char (point-min)) | ||
| 1866 | (let ((max 0)) | ||
| 1867 | (while (not (eobp)) | ||
| 1868 | (end-of-line) | ||
| 1869 | (setq max (max max (current-column))) | ||
| 1870 | (forward-line 1)) | ||
| 1871 | max)) | ||
| 1872 | (if (get-buffer-window) | ||
| 1873 | (car (window-text-pixel-size nil (point-min) (point-max))) | ||
| 1874 | (save-window-excursion | ||
| 1875 | (set-window-buffer nil (current-buffer)) | ||
| 1876 | (car (window-text-pixel-size nil (point-min) (point-max))))))) | ||
| 1877 | |||
| 1702 | (defun shr-render-td (dom width fill) | 1878 | (defun shr-render-td (dom width fill) |
| 1879 | (let ((cache (intern (format "shr-td-cache-%s-%s" width fill)))) | ||
| 1880 | (or (dom-attr dom cache) | ||
| 1881 | (and fill | ||
| 1882 | (let (result) | ||
| 1883 | (dolist (attr (dom-attributes dom)) | ||
| 1884 | (let ((name (symbol-name (car attr)))) | ||
| 1885 | (when (string-match "shr-td-cache-\\([0-9]+\\)-nil" name) | ||
| 1886 | (let ((cache-width (string-to-number | ||
| 1887 | (match-string 1 name)))) | ||
| 1888 | (when (and (>= cache-width width) | ||
| 1889 | (<= (car (cdr attr)) width)) | ||
| 1890 | (setq result (cdr attr))))))) | ||
| 1891 | result)) | ||
| 1892 | (let ((result (shr-render-td-1 dom width fill))) | ||
| 1893 | (dom-set-attribute dom cache result) | ||
| 1894 | result)))) | ||
| 1895 | |||
| 1896 | (defun shr-render-td-1 (dom width fill) | ||
| 1703 | (with-temp-buffer | 1897 | (with-temp-buffer |
| 1704 | (let ((bgcolor (dom-attr dom 'bgcolor)) | 1898 | (let ((bgcolor (dom-attr dom 'bgcolor)) |
| 1705 | (fgcolor (dom-attr dom 'fgcolor)) | 1899 | (fgcolor (dom-attr dom 'fgcolor)) |
| 1706 | (style (dom-attr dom 'style)) | 1900 | (style (dom-attr dom 'style)) |
| 1707 | (shr-stylesheet shr-stylesheet) | 1901 | (shr-stylesheet shr-stylesheet) |
| 1708 | actual-colors) | 1902 | (max-width 0) |
| 1903 | natural-width) | ||
| 1709 | (when style | 1904 | (when style |
| 1710 | (setq style (and (string-match "color" style) | 1905 | (setq style (and (string-match "color" style) |
| 1711 | (shr-parse-style style)))) | 1906 | (shr-parse-style style)))) |
| 1712 | (when bgcolor | 1907 | (when bgcolor |
| 1713 | (setq style (nconc (list (cons 'background-color bgcolor)) style))) | 1908 | (setq style (nconc (list (cons 'background-color bgcolor)) |
| 1909 | style))) | ||
| 1714 | (when fgcolor | 1910 | (when fgcolor |
| 1715 | (setq style (nconc (list (cons 'color fgcolor)) style))) | 1911 | (setq style (nconc (list (cons 'color fgcolor)) style))) |
| 1716 | (when style | 1912 | (when style |
| @@ -1718,6 +1914,22 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1718 | (let ((shr-internal-width width) | 1914 | (let ((shr-internal-width width) |
| 1719 | (shr-indentation 0)) | 1915 | (shr-indentation 0)) |
| 1720 | (shr-descend dom)) | 1916 | (shr-descend dom)) |
| 1917 | (save-window-excursion | ||
| 1918 | (set-window-buffer nil (current-buffer)) | ||
| 1919 | (unless fill | ||
| 1920 | (setq natural-width | ||
| 1921 | (or (dom-attr dom 'shr-td-cache-natural) | ||
| 1922 | (let ((natural (max (shr-pixel-buffer-width) | ||
| 1923 | (shr-dom-max-natural-width dom 0)))) | ||
| 1924 | (dom-set-attribute dom 'shr-td-cache-natural natural) | ||
| 1925 | natural)))) | ||
| 1926 | (if (and natural-width | ||
| 1927 | (<= natural-width width)) | ||
| 1928 | (setq max-width natural-width) | ||
| 1929 | (let ((shr-internal-width width)) | ||
| 1930 | (shr-fill-lines (point-min) (point-max)) | ||
| 1931 | (setq max-width (shr-pixel-buffer-width))))) | ||
| 1932 | (goto-char (point-max)) | ||
| 1721 | ;; Delete padding at the bottom of the TDs. | 1933 | ;; Delete padding at the bottom of the TDs. |
| 1722 | (delete-region | 1934 | (delete-region |
| 1723 | (point) | 1935 | (point) |
| @@ -1726,48 +1938,31 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1726 | (end-of-line) | 1938 | (end-of-line) |
| 1727 | (point))) | 1939 | (point))) |
| 1728 | (goto-char (point-min)) | 1940 | (goto-char (point-min)) |
| 1729 | (let ((max 0)) | 1941 | (list max-width |
| 1730 | (while (not (eobp)) | 1942 | natural-width |
| 1731 | (end-of-line) | 1943 | (count-lines (point-min) (point-max)) |
| 1732 | (setq max (max max (current-column))) | 1944 | (split-string (buffer-string) "\n") |
| 1733 | (forward-line 1)) | 1945 | (if (dom-attr dom 'colspan) |
| 1734 | (when fill | 1946 | (string-to-number (dom-attr dom 'colspan)) |
| 1735 | (goto-char (point-min)) | 1947 | 1) |
| 1736 | ;; If the buffer is totally empty, then put a single blank | 1948 | (cdr (assq 'color shr-stylesheet)) |
| 1737 | ;; line here. | 1949 | (cdr (assq 'background-color shr-stylesheet)))))) |
| 1738 | (if (zerop (buffer-size)) | 1950 | |
| 1739 | (insert (make-string width ? )) | 1951 | (defun shr-dom-max-natural-width (dom max) |
| 1740 | ;; Otherwise, fill the buffer. | 1952 | (if (eq (dom-tag dom) 'table) |
| 1741 | (let ((align (dom-attr dom 'align)) | 1953 | (max max (or |
| 1742 | length) | 1954 | (loop for line in (dom-attr dom 'shr-suggested-widths) |
| 1743 | (while (not (eobp)) | 1955 | maximize (+ |
| 1744 | (end-of-line) | 1956 | shr-table-separator-length |
| 1745 | (setq length (- width (current-column))) | 1957 | (loop for elem in line |
| 1746 | (when (> length 0) | 1958 | summing |
| 1747 | (cond | 1959 | (+ (cdr elem) |
| 1748 | ((equal align "right") | 1960 | (* 2 shr-table-separator-length))))) |
| 1749 | (beginning-of-line) | 1961 | 0)) |
| 1750 | (insert (make-string length ? ))) | 1962 | (dolist (child (dom-children dom)) |
| 1751 | ((equal align "center") | 1963 | (unless (stringp child) |
| 1752 | (insert (make-string (/ length 2) ? )) | 1964 | (setq max (max (shr-dom-max-natural-width child max))))) |
| 1753 | (beginning-of-line) | 1965 | max)) |
| 1754 | (insert (make-string (- length (/ length 2)) ? ))) | ||
| 1755 | (t | ||
| 1756 | (insert (make-string length ? ))))) | ||
| 1757 | (forward-line 1)))) | ||
| 1758 | (when style | ||
| 1759 | (setq actual-colors | ||
| 1760 | (shr-colorize-region | ||
| 1761 | (point-min) (point-max) | ||
| 1762 | (cdr (assq 'color shr-stylesheet)) | ||
| 1763 | (cdr (assq 'background-color shr-stylesheet)))))) | ||
| 1764 | (if fill | ||
| 1765 | (list max | ||
| 1766 | (count-lines (point-min) (point-max)) | ||
| 1767 | (split-string (buffer-string) "\n") | ||
| 1768 | nil | ||
| 1769 | (car actual-colors)) | ||
| 1770 | max))))) | ||
| 1771 | 1966 | ||
| 1772 | (defun shr-buffer-width () | 1967 | (defun shr-buffer-width () |
| 1773 | (goto-char (point-min)) | 1968 | (goto-char (point-min)) |
| @@ -1788,7 +1983,8 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1788 | (aset widths i (max (truncate (* (aref columns i) | 1983 | (aset widths i (max (truncate (* (aref columns i) |
| 1789 | total-percentage | 1984 | total-percentage |
| 1790 | (- shr-internal-width | 1985 | (- shr-internal-width |
| 1791 | (1+ (length columns))))) | 1986 | (* (1+ (length columns)) |
| 1987 | shr-table-separator-pixel-width)))) | ||
| 1792 | 10))) | 1988 | 10))) |
| 1793 | widths)) | 1989 | widths)) |
| 1794 | 1990 | ||
| @@ -1798,9 +1994,8 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1798 | (dolist (row (dom-non-text-children dom)) | 1994 | (dolist (row (dom-non-text-children dom)) |
| 1799 | (when (eq (dom-tag row) 'tr) | 1995 | (when (eq (dom-tag row) 'tr) |
| 1800 | (let ((i 0)) | 1996 | (let ((i 0)) |
| 1801 | (dolist (column (dom-children row)) | 1997 | (dolist (column (dom-non-text-children row)) |
| 1802 | (when (and (not (stringp column)) | 1998 | (when (memq (dom-tag column) '(td th)) |
| 1803 | (memq (dom-tag column) '(td th))) | ||
| 1804 | (let ((width (dom-attr column 'width))) | 1999 | (let ((width (dom-attr column 'width))) |
| 1805 | (when (and width | 2000 | (when (and width |
| 1806 | (string-match "\\([0-9]+\\)%" width) | 2001 | (string-match "\\([0-9]+\\)%" width) |