;;; Code:
+(eval-when-compile (require 'cl))
(require 'browse-url)
(defgroup shr nil
:group 'shr
:type 'regexp)
+(defcustom shr-table-line ?-
+ "Character used to draw table line."
+ :group 'shr
+ :type 'char)
+
+(defcustom shr-table-corner ?+
+ "Character used to draw table corner."
+ :group 'shr
+ :type 'char)
+
+(defcustom shr-hr-line ?-
+ "Character used to draw hr line."
+ :group 'shr
+ :type 'char)
+
(defvar shr-content-function nil
"If bound, this should be a function that will return the content.
This is used for cid: URLs, and the function is called with the
(shr-descend sub)))))
(defun shr-insert (text)
- (when (eq shr-state 'image)
+ (when (and (eq shr-state 'image)
+ (not (string-match "\\`[ \t\n]+\\'" text)))
(insert "\n")
(setq shr-state nil))
(cond
(let ((first t)
column)
(when (and (string-match "\\`[ \t\n]" text)
- (not (bolp)))
+ (not (bolp))
+ (not (eq (char-after (1- (point))) ? )))
(insert " "))
(dolist (elem (split-string text))
(when (and (bolp)
(unless shr-start
(setq shr-start (point)))
(insert elem)
- (when (> (current-column) shr-width)
+ (when (> (shr-current-column) shr-width)
(if (not (search-backward " " (line-beginning-position) t))
(insert "\n")
(delete-char 1)
(unless (string-match "[ \t\n]\\'" text)
(delete-char -1))))))
+(defun shr-find-fill-point ()
+ (let ((found nil))
+ (while (and (not found)
+ (not (bolp)))
+ (when (or (eq (preceding-char) ? )
+ (aref fill-find-break-point-function-table (preceding-char)))
+ (setq found (point)))
+ (backward-char 1))
+ (or found
+ (end-of-line))))
+
+(defun shr-current-column ()
+ (let ((column 0))
+ (save-excursion
+ (beginning-of-line)
+ (while (not (eolp))
+ (incf column (char-width (following-char)))
+ (forward-char 1)))
+ column))
+
(defun shr-ensure-newline ()
(unless (zerop (current-column))
(insert "\n")))
(defun shr-ensure-paragraph ()
(unless (bobp)
- (if (bolp)
+ (if (<= (current-column) shr-indentation)
(unless (save-excursion
(forward-line -1)
(looking-at " *$"))
(insert "\n\n")))))
(defun shr-indent ()
- (insert (make-string shr-indentation ? )))
+ (when (> shr-indentation 0)
+ (insert (make-string shr-indentation ? ))))
(defun shr-fontize-cont (cont &rest types)
(let (shr-start)
(defun shr-tag-p (cont)
(shr-ensure-paragraph)
+ (shr-indent)
(shr-generic cont)
(shr-ensure-paragraph))
(defun shr-tag-pre (cont)
(let ((shr-folding-mode 'none))
(shr-ensure-newline)
+ (shr-indent)
(shr-generic cont)
(shr-ensure-newline)))
(defun shr-tag-blockquote (cont)
(shr-ensure-paragraph)
+ (shr-indent)
(let ((shr-indentation (+ shr-indentation 4)))
(shr-generic cont))
(shr-ensure-paragraph))
(shr-ensure-paragraph))
(defun shr-tag-li (cont)
- (shr-ensure-newline)
+ (shr-ensure-paragraph)
+ (shr-indent)
(let* ((bullet
(if (numberp shr-list-mode)
(prog1
(defun shr-tag-br (cont)
(unless (bobp)
- (insert "\n"))
+ (insert "\n")
+ (shr-indent))
(shr-generic cont))
(defun shr-tag-h1 (cont)
(defun shr-tag-h6 (cont)
(shr-heading cont))
+(defun shr-tag-hr (cont)
+ (shr-ensure-newline)
+ (insert (make-string shr-width shr-hr-line) "\n"))
+
;;; Table rendering algorithm.
;; Table rendering is the only complicated thing here. We do this by
(defun shr-insert-table-ruler (widths)
(shr-indent)
- (insert "+")
+ (insert shr-table-corner)
(dotimes (i (length widths))
- (insert (make-string (aref widths i) ?-) ?+))
+ (insert (make-string (aref widths i) shr-table-line) shr-table-corner))
(insert "\n"))
(defun shr-table-widths (table suggested-widths)
(aset natural-widths i (max (aref natural-widths i)
(cadr column)))
(setq i (1+ i)))))
- (let ((extra (- (reduce '+ suggested-widths)
- (reduce '+ widths)))
+ (let ((extra (- (apply '+ (append suggested-widths nil))
+ (apply '+ (append widths nil))))
(expanded-columns 0))
(when (> extra 0)
(dotimes (i length)