emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] shr-fontified f00ab0c 1/2: Allow rendering using fixed-wid


From: Lars Ingebrigtsen
Subject: [Emacs-diffs] shr-fontified f00ab0c 1/2: Allow rendering using fixed-width fonts
Date: Sat, 07 Feb 2015 11:35:33 +0000

branch: shr-fontified
commit f00ab0c65313f51585b75e2ace39537ba73a2323
Author: Lars Magne Ingebrigtsen <address@hidden>
Commit: Lars Magne Ingebrigtsen <address@hidden>

    Allow rendering using fixed-width fonts
    
    (shr-use-fonts): New variable used throughout.
---
 lisp/ChangeLog  |    1 +
 lisp/net/shr.el |  212 ++++++++++++++++++++++++++++++++++---------------------
 2 files changed, 132 insertions(+), 81 deletions(-)

diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index ea5e500..0e209b8 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -3,6 +3,7 @@
        * net/shr.el (shr-tag-table-1): Add further caching when computing
        natural and sketch widths.
        (shr-insert-table-ruler): Compute the separator pixel width only once.
+       (shr-use-fonts): New variable used throughout.
 
 2015-02-06  Lars Ingebrigtsen  <address@hidden>
 
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index b401db8..84ee737 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -57,6 +57,12 @@ fit these criteria."
   :group 'shr
   :type '(choice (const nil) regexp))
 
+(defcustom shr-use-fonts nil
+  "If non-nil, use proportional fonts for text."
+  :version "25.1"
+  :group 'shr
+  :type 'boolean)
+
 (defcustom shr-table-horizontal-line nil
   "Character used to draw horizontal table lines.
 If nil, don't draw horizontal table lines."
@@ -152,6 +158,7 @@ cid: URL as the argument.")
 (defvar shr-inhibit-decoration nil)
 (defvar shr-table-separator-length 1)
 (defvar shr-table-separator-pixel-width 0)
+(defvar shr-table-id nil)
 
 (defvar shr-map
   (let ((map (make-sparse-keymap)))
@@ -215,8 +222,10 @@ DOM should be a parse tree as generated by
        (shr-font-cache (make-hash-table :test 'eq))
        (shr-fill-cache (make-hash-table :test 'equal))
        (shr-internal-width (or shr-width
-                               (- (window-pixel-width)
-                                  (* (frame-fringe-width) 2)))))
+                               (if (not shr-use-fonts)
+                                   (- (window-width) 2)
+                                 (- (window-pixel-width)
+                                    (* (frame-fringe-width) 2))))))
     (shr-descend dom)
     (shr-remove-trailing-whitespace start (point))
     (when shr-warning
@@ -458,11 +467,13 @@ size, and full-buffer size."
   (load "kinsoku" nil t))
 
 (defun shr-pixel-column ()
-  (if (not (get-buffer-window (current-buffer)))
-      (save-window-excursion
-       (set-window-buffer nil (current-buffer))
-       (car (window-text-pixel-size nil (line-beginning-position) (point))))
-    (car (window-text-pixel-size nil (line-beginning-position) (point)))))
+  (if (not shr-use-fonts)
+      (current-column)
+    (if (not (get-buffer-window (current-buffer)))
+       (save-window-excursion
+         (set-window-buffer nil (current-buffer))
+         (car (window-text-pixel-size nil (line-beginning-position) (point))))
+      (car (window-text-pixel-size nil (line-beginning-position) (point))))))
 
 (defun shr-string-pixel-width (string)
   (with-temp-buffer
@@ -501,7 +512,8 @@ size, and full-buffer size."
        (when bolp
          (put-text-property start (1+ start)
                             'shr-indentation shr-indentation))
-       (put-text-property start (point) 'face 'variable-pitch))))))
+       (when shr-use-fonts
+         (put-text-property start (point) 'face 'variable-pitch)))))))
 
 (defun shr-fold-lines (start end)
   (if (<= shr-internal-width 0)
@@ -517,22 +529,26 @@ size, and full-buffer size."
       (goto-char (point-max)))))
 
 (defun shr-goto-pixel-column (pixels)
-  (vertical-motion (cons (/ pixels (frame-char-width)) 0))
-  ;; Vertical-motion goes to the char before or on the pixel, so
-  ;; advance one char.
-  (unless (eolp)
-    (forward-char 1)))
+  (if (not shr-use-fonts)
+      (move-to-column pixels)
+    (vertical-motion (cons (/ pixels (frame-char-width)) 0))
+    ;; Vertical-motion goes to the char before or on the pixel, so
+    ;; advance one char.
+    (unless (eolp)
+      (forward-char 1))))
 
-(defun shr-vertical-motion (spec)
-  (vertical-motion spec))
+(defun shr-vertical-motion (column)
+  (if (not shr-use-fonts)
+      (move-to-column column)
+    (vertical-motion
+     (cons (/ shr-internal-width (frame-char-width)) 0))))
 
 (defun shr-fold-line ()
-  (let ((indentation (get-text-property (point) 'shr-indentation))
-       (spec (cons (/ shr-internal-width (frame-char-width)) 0)))
+  (let ((indentation (get-text-property (point) 'shr-indentation)))
     (put-text-property (point) (1+ (point)) 'shr-indentation nil)
     (when (> indentation 0)
       (insert (make-string indentation ?\s)))
-    (shr-vertical-motion spec)
+    (shr-vertical-motion shr-internal-width)
     (unless (eolp)
       (forward-char 1))
     (while (not (eolp))
@@ -542,7 +558,7 @@ size, and full-buffer size."
       (when (= (preceding-char) ?\s)
        (delete-char -1))
       (insert "\n")
-      (shr-vertical-motion spec)
+      (shr-vertical-motion shr-internal-width)
       (unless (eolp)
        (forward-char 1)))))
 
@@ -1151,9 +1167,10 @@ ones, in case fg and bg are nil."
                  (value (replace-regexp-in-string "^ +\\| +$" "" (cadr elem))))
              (when (string-match " *!important\\'" value)
                (setq value (substring value 0 (match-beginning 0))))
-             (push (cons (intern name obarray)
-                         value)
-                   plist)))))
+             (unless (equal value "inherit")
+               (push (cons (intern name obarray)
+                           value)
+                     plist))))))
       plist)))
 
 (defun shr-tag-base (dom)
@@ -1411,7 +1428,8 @@ The preference is a float determined from 
`shr-prefer-media-type'."
   (shr-generic dom))
 
 (defun shr-tag-h1 (dom)
-  (shr-heading dom '(variable-pitch (:height 1.5 :weight bold))))
+  (shr-heading dom (and shr-use-fonts
+                       '(variable-pitch (:height 1.5 :weight bold)))))
 
 (defun shr-tag-h2 (dom)
   (shr-heading dom 'bold))
@@ -1464,18 +1482,18 @@ The preference is a float determined from 
`shr-prefer-media-type'."
         (columns (shr-column-specs dom))
         ;; Compute how many pixels wide each TD should be.
         (suggested-widths (shr-pro-rate-columns columns))
-        ;; Do a "test rendering" to see how big each TD is (this can
-        ;; be smaller (if there's little text) or bigger (if there's
-        ;; unbreakable text).
-        (sketch (or (dom-attr dom 'shr-suggested-widths)
-                    (shr-make-table dom suggested-widths nil
-                                    'shr-suggested-widths)))
         ;; Compute the "natural" width by setting each column to 5000
         ;; characters and see how wide they really render.
         (natural (or (dom-attr dom 'shr-natural-widths)
                      (shr-make-table
                       dom (make-vector (length columns) 5000)
                       nil 'shr-natural-widths)))
+        ;; Do a "test rendering" to see how big each TD is (this can
+        ;; be smaller (if there's little text) or bigger (if there's
+        ;; unbreakable text).
+        (sketch (or (dom-attr dom 'shr-suggested-widths)
+                    (shr-make-table dom suggested-widths nil
+                                    'shr-suggested-widths)))
         (sketch-widths (shr-table-widths sketch natural suggested-widths)))
     ;; This probably won't work very well.
     (when (> (+ (loop for width across sketch-widths
@@ -1613,15 +1631,20 @@ The preference is a float determined from 
`shr-prefer-media-type'."
          (dotimes (i (nth 3 column))
            (if (> column-number (1- (length widths)))
                (setq align (+ align 20))
-             (setq align (+ align 20 (aref widths column-number))))
+             (setq align (+ align
+                            (aref widths column-number)
+                            (* 2 shr-table-separator-pixel-width))))
            (setq column-number (1+ column-number)))
-         (let ((lines (nth 2 column)))
+         (let ((lines (nth 2 column))
+               (pixel-align (if (not shr-use-fonts)
+                                (* align (frame-char-width))
+                              align)))
            (dolist (line lines)
              (end-of-line)
              (let ((start (point)))
                (insert line
                        (propertize " "
-                                   'display `(space :align-to (,align))
+                                   'display `(space :align-to (,pixel-align))
                                    'shr-table-indent shr-table-id)
                        shr-table-vertical-line)
                (shr-colorize-region
@@ -1633,7 +1656,7 @@ The preference is a float determined from 
`shr-prefer-media-type'."
              (end-of-line)
              (let ((start (point)))
                (insert (propertize " "
-                                   'display `(space :align-to (,align))
+                                   'display `(space :align-to (,pixel-align))
                                    'shr-table-indent shr-table-id)
                        shr-table-vertical-line)
                (shr-colorize-region
@@ -1652,8 +1675,10 @@ The preference is a float determined from 
`shr-prefer-media-type'."
                         start 'shr-table-id nil end))
            end)
     (goto-char start)
-    (let ((id (get-text-property (point) 'shr-table-id))
-         (base (shr-pixel-column)))
+    (let* ((shr-use-fonts t)
+          (id (get-text-property (point) 'shr-table-id))
+          (base (shr-pixel-column))
+          elem)
       (save-excursion
        (while (setq elem (text-property-any (point) end 'shr-table-indent id))
          (goto-char elem)
@@ -1803,54 +1828,79 @@ The preference is a float determined from 
`shr-prefer-media-type'."
     (nreverse trs)))
 
 (defun shr-pixel-buffer-width ()
-  (if (get-buffer-window)
-      (car (window-text-pixel-size nil (point-min) (point-max)))
-    (save-window-excursion
-      (set-window-buffer nil (current-buffer))
-      (car (window-text-pixel-size nil (point-min) (point-max))))))
+  (if (not shr-use-fonts)
+      (save-excursion
+       (goto-char (point-min))
+       (let ((max 0))
+         (while (not (eobp))
+           (end-of-line)
+           (setq max (max max (current-column)))
+           (forward-line 1))
+         max))
+    (if (get-buffer-window)
+       (car (window-text-pixel-size nil (point-min) (point-max)))
+      (save-window-excursion
+       (set-window-buffer nil (current-buffer))
+       (car (window-text-pixel-size nil (point-min) (point-max)))))))
 
 (defun shr-render-td (dom width fill)
-  (with-temp-buffer
-    (let ((bgcolor (dom-attr dom 'bgcolor))
-         (fgcolor (dom-attr dom 'fgcolor))
-         (style (dom-attr dom 'style))
-         (shr-stylesheet shr-stylesheet)
-         (max-width 0))
-      (when style
-       (setq style (and (string-match "color" style)
-                        (shr-parse-style style))))
-      (when bgcolor
-       (setq style (nconc (list (cons 'background-color bgcolor)) style)))
-      (when fgcolor
-       (setq style (nconc (list (cons 'color fgcolor)) style)))
-      (when style
-       (setq shr-stylesheet (append style shr-stylesheet)))
-      (let ((shr-internal-width width)
-           (shr-indentation 0))
-       (shr-descend dom))
-      (let ((shr-internal-width width))
-       (unless (= shr-internal-width 5000)
-         (shr-fold-lines (point-min) (point-max)))
-       (setq max-width (shr-pixel-buffer-width)))
-      (goto-char (point-max))
-      ;; Delete padding at the bottom of the TDs.
-      (delete-region
-       (point)
-       (progn
-        (skip-chars-backward " \t\n")
-        (end-of-line)
-        (point)))
-      (goto-char (point-min))
-      (if fill
-         (list max-width
-               (count-lines (point-min) (point-max))
-               (split-string (buffer-string) "\n")
-               (if (dom-attr dom 'colspan)
-                   (string-to-number (dom-attr dom 'colspan))
-                 1)
-               (cdr (assq 'color shr-stylesheet))
-               (cdr (assq 'background-color shr-stylesheet)))
-       max-width))))
+  (let ((cache (intern (format "shr-td-cache-%s-%s" width fill))))
+    (or (dom-attr dom cache)
+       (let ((natural (dom-attr dom 'shr-td-cache-natural)))
+         (and (not fill)
+              natural
+              (>= width natural)
+              natural))
+       (with-temp-buffer
+         (let ((bgcolor (dom-attr dom 'bgcolor))
+               (fgcolor (dom-attr dom 'fgcolor))
+               (style (dom-attr dom 'style))
+               (shr-stylesheet shr-stylesheet)
+               (max-width 0))
+           (when style
+             (setq style (and (string-match "color" style)
+                              (shr-parse-style style))))
+           (when bgcolor
+             (setq style (nconc (list (cons 'background-color bgcolor))
+                                style)))
+           (when fgcolor
+             (setq style (nconc (list (cons 'color fgcolor)) style)))
+           (when style
+             (setq shr-stylesheet (append style shr-stylesheet)))
+           (let ((shr-internal-width width)
+                 (shr-indentation 0))
+             (shr-descend dom))
+           (let ((shr-internal-width width))
+             (unless (= shr-internal-width 5000)
+               (shr-fold-lines (point-min) (point-max)))
+             (setq max-width (shr-pixel-buffer-width)))
+           (goto-char (point-max))
+           ;; Delete padding at the bottom of the TDs.
+           (delete-region
+            (point)
+            (progn
+              (skip-chars-backward " \t\n")
+              (end-of-line)
+              (point)))
+           (goto-char (point-min))
+           (let ((result
+                  (if fill
+                      (list max-width
+                            (count-lines (point-min) (point-max))
+                            (split-string (buffer-string) "\n")
+                            (if (dom-attr dom 'colspan)
+                                (string-to-number (dom-attr dom 'colspan))
+                              1)
+                            (cdr (assq 'color shr-stylesheet))
+                            (cdr (assq 'background-color shr-stylesheet)))
+                    max-width)))
+             (when (and (>= width 5000)
+                        (not fill))
+               (dom-set-attribute dom 'shr-td-cache-natural result ))
+             (when (eq cache 'shr-td-cache-2486-nil)
+               (debug))
+             (dom-set-attribute dom cache result)
+             result))))))
 
 (defun shr-buffer-width ()
   (goto-char (point-min))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]