(require 'browse-url)
(require 'subr-x)
(require 'dom)
+(require 'seq)
(defgroup shr nil
"Simple HTML Renderer"
(url-expand-file-name url (concat (car base) (cadr base))))))
(defun shr-ensure-newline ()
- (unless (zerop (current-column))
- (insert "\n")))
+ (unless (bobp)
+ (let ((prefix (get-text-property (line-beginning-position)
+ 'shr-prefix-length)))
+ (unless (or (zerop (current-column))
+ (and prefix
+ (= prefix (- (point) (line-beginning-position)))))
+ (insert "\n")))))
(defun shr-ensure-paragraph ()
(unless (bobp)
(line-end-position))
(line-end-position)))))
(delete-region (match-beginning 0) (match-end 0)))
+ ;; We have a single blank line.
+ ((and (eolp) (bolp))
+ (insert "\n"))
+ ;; Insert new paragraph.
(t
(insert "\n\n"))))))
(let ((param (match-string 4 data))
(payload (url-unhex-string (match-string 5 data))))
(when (string-match "^.*\\(;[ \t]*base64\\)$" param)
- (setq payload (base64-decode-string payload)))
+ (setq payload (ignore-errors
+ (base64-decode-string payload))))
payload)))
;; Behind display-graphic-p test.
(image-animated-p image))))
(image-animate image nil 60)))
image)
- (insert alt)))
+ (insert (or alt ""))))
(defun shr-rescale-image (data &optional content-type)
"Rescale DATA, if too big, to fit the current buffer."
(and shr-blocked-images
(string-match shr-blocked-images url)))
(setq shr-start (point))
- (if (> (string-width alt) 8)
- (shr-insert (truncate-string-to-width alt 8))
- (shr-insert alt)))
+ (shr-insert alt))
((and (not shr-ignore-cache)
(url-is-cached (shr-encode-url url)))
(funcall shr-put-image-function (shr-get-image-data url) alt))
(shr-ensure-paragraph)
(let ((shr-list-mode 'ul))
(shr-generic dom))
+ ;; If we end on an empty <li>, then make sure we really end on a new
+ ;; paragraph.
+ (unless (bolp)
+ (insert "\n"))
(shr-ensure-paragraph))
(defun shr-tag-ol (dom)
(shr-insert-table (shr-make-table dom sketch-widths t) sketch-widths)))
(defun shr-table-body (dom)
- (let ((tbodies (dom-by-tag dom 'tbody)))
+ (let ((tbodies (seq-filter (lambda (child)
+ (eq (dom-tag child) 'tbody))
+ (dom-non-text-children dom))))
(cond
((null tbodies)
dom)
align)))
(dolist (line lines)
(end-of-line)
- (let ((start (point)))
- (insert
- line
- (propertize " "
- 'display `(space :align-to (,pixel-align))
- 'face (and (> (length line) 0)
- (shr-face-background
- (get-text-property
- (1- (length line)) 'face line)))
- 'shr-table-indent shr-table-id)
- shr-table-vertical-line)
+ (let ((start (point))
+ (background (and (> (length line) 0)
+ (shr-face-background
+ (get-text-property
+ (1- (length line)) 'face line))))
+ (space (propertize
+ " "
+ 'display `(space :align-to (,pixel-align))
+ 'shr-table-indent shr-table-id)))
+ (when background
+ (setq space (propertize space 'face background)))
+ (insert line space shr-table-vertical-line)
(shr-colorize-region
start (1- (point)) (nth 5 column) (nth 6 column)))
(forward-line 1))
(defun shr-face-background (face)
(and (consp face)
- (let ((background nil))
- (dolist (elem face)
- (when (and (consp elem)
- (eq (car elem) :background))
- (setq background (cadr elem))))
- (and background
- (list :background background)))))
+ (or (and (plist-get face :background)
+ (list :background (plist-get face :background)))
+ (let ((background nil))
+ (dolist (elem face)
+ (when (and (consp elem)
+ (eq (car elem) :background)
+ (not background))
+ (setq background (cadr elem))))
+ (and background
+ (list :background background))))))
(defun shr-expand-alignments (start end)
(while (< (setq start (next-single-property-change