aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasilij Schneidermann <mail@vasilij.de>2024-08-10 15:59:05 +0200
committerVasilij Schneidermann <mail@vasilij.de>2024-08-10 15:59:05 +0200
commit32ded63420134d9995426910c5f5d9f5bd29fff8 (patch)
tree6955845b63d56691ecf361a60c17462bc57da8df
parent66820c2c5bec54b080c9d7ed9e777611bae70776 (diff)
Add workaround to render svg>image case
It's very common to have `<svg ...><image href="..."></svg>` for cover pages. However, not all uses of the `<svg>` tag use `<image>` inside, for example some EPUB documents use it for vector logos instead. The given workaround checks whether the SVG node can be safely replaced with an equivalent image and otherwise falls back to regular SVG rendering.
-rw-r--r--nov.el29
1 files changed, 29 insertions, 0 deletions
diff --git a/nov.el b/nov.el
index 946564b..3fe78b6 100644
--- a/nov.el
+++ b/nov.el
@@ -515,6 +515,8 @@ Each alist item consists of the identifier and full path."
(mapcar 'nov-urldecode (list (url-filename url) (url-target url))))
;; adapted from `shr-rescale-image'
+;; TODO: adjust to latest shr code (which added zooming support)
+;; TODO: support width/height as supplied in img/image/svg attributes
(defun nov-insert-image (path alt)
"Insert an image for PATH at point, falling back to ALT.
This function honors `shr-max-image-proportion' if possible."
@@ -556,6 +558,31 @@ internal ones."
(setq url (expand-file-name (nov-urldecode url)))
(nov-insert-image url alt))))
+(defun nov--render-image (dom &optional url)
+ (let ((img-tag (dom-node 'img
+ (dom-attributes dom)
+ (dom-children dom))))
+ (nov-render-img img-tag url)))
+
+(defun nov-render-svg (dom)
+ "Custom <svg> rendering function for DOM.
+If the SVG element only contains <image> tags with an internal
+URL, insert each image with `nov-insert-image'. Otherwise, fall
+back to regular <img> rendering via `nov-render-img' (for
+external URLs) or regular SVG rendering via `shr-tag-svg'."
+ (when (and (image-type-available-p 'svg)
+ (not shr-inhibit-images))
+ (let ((children (dom-children dom)))
+ (if (seq-every-p (lambda (child) (eq (dom-tag child) 'image)) children)
+ (dolist (image-tag children)
+ (let ((url (or (dom-attr image-tag 'href)
+ (dom-attr image-tag 'xlink:href))))
+ (if (nov-external-url-p url)
+ (nov--render-image dom)
+ (nov-insert-image
+ (expand-file-name (nov-urldecode url)) ""))))
+ (shr-tag-svg dom)))))
+
(defun nov-render-title (dom)
"Custom <title> rendering function for DOM.
Sets `header-line-format' according to `nov-header-line-format'."
@@ -578,6 +605,8 @@ Sets `header-line-format' according to `nov-header-line-format'."
(defvar nov-shr-rendering-functions
'(;; default function uses url-retrieve and fails on local images
(img . nov-render-img)
+ ;; likewise, but for SVG tags containing local images
+ (svg . nov-render-svg)
;; titles are rendered *inside* the document by default
(title . nov-render-title))
"Alist of rendering functions used with `shr-render-region'.")