(eval-when-compile (require 'cl))
(require 'browse-url)
+(unless (aref (char-category-set (make-char 'japanese-jisx0208 33 35)) ?>)
+ (load "kinsoku" nil t))
(defgroup shr nil
"Simple HTML Renderer"
(defvar shr-inhibit-images nil)
(defvar shr-list-mode nil)
(defvar shr-content-cache nil)
+(defvar shr-kinsoku-shorten nil)
(defvar shr-map
(let ((map (make-sparse-keymap)))
(define-key map "I" 'shr-insert-image)
(define-key map "u" 'shr-copy-url)
(define-key map "v" 'shr-browse-url)
+ (define-key map "o" 'shr-save-contents)
(define-key map "\r" 'shr-browse-url)
map))
(insert "\n"))
(put-text-property (1- (point)) (point) 'shr-break t)
;; No space is needed at the beginning of a line.
- (if (eq (following-char) ? )
- (delete-char 1)))
+ (when (eq (following-char) ? )
+ (delete-char 1)))
(when (> shr-indentation 0)
(shr-indent))
(end-of-line))
(unless (string-match "[ \t\n]\\'" text)
(delete-char -1)))))
-(eval-and-compile (autoload 'kinsoku-longer "kinsoku"))
-
(defun shr-find-fill-point ()
- (let ((found nil))
- (while (and (not found)
- (> (current-column) shr-indentation))
- (when (and (or (eq (preceding-char) ? )
- (aref fill-find-break-point-function-table
- (preceding-char)))
- (<= (current-column) shr-width))
- (setq found t))
- (backward-char 1)
- (when (bolp)
+ (when (> (move-to-column shr-width) shr-width)
+ (backward-char 1))
+ (let (failed)
+ (while (not
+ (or (setq failed (= (current-column) shr-indentation))
+ (eq (preceding-char) ? )
+ (eq (following-char) ? )
+ (aref fill-find-break-point-function-table (preceding-char))))
+ (backward-char 1))
+ (if failed
;; There's no breakable point, so we give it up.
- (end-of-line)
- (while (aref fill-find-break-point-function-table
- (preceding-char))
- (backward-char 1))
- (setq found 'failed)))
- (cond ((eq found t)
- ;; Don't put kinsoku-bol characters at the beginning of a line.
- (or (eobp)
- (kinsoku-longer)
- (not (aref fill-find-break-point-function-table
- (following-char)))
- (forward-char 1)))
- (found t)
- (t
- (end-of-line)
- nil))))
+ (progn
+ (end-of-line)
+ (while (aref fill-find-break-point-function-table (preceding-char))
+ (backward-char 1))
+ nil)
+ (or (eolp)
+ ;; Don't put kinsoku-bol characters at the beginning of a line,
+ ;; or kinsoku-eol characters at the end of a line,
+ (let ((count 4))
+ (if shr-kinsoku-shorten
+ (while (and
+ (> count 0)
+ (or (aref (char-category-set (preceding-char)) ?<)
+ (aref (char-category-set (following-char)) ?>)))
+ (backward-char 1))
+ (while (and (> count 0)
+ (aref (char-category-set (following-char)) ?>))
+ (forward-char 1)))
+ (when (eq (following-char) ? )
+ (forward-char 1))
+ t)))))
(defun shr-ensure-newline ()
(unless (zerop (current-column))
(message "No link under point")
(browse-url url))))
+(defun shr-save-contents (directory)
+ "Save the contents from URL in a file."
+ (interactive "DSave contents of URL to directory: ")
+ (let ((url (get-text-property (point) 'shr-url)))
+ (if (not url)
+ (message "No link under point")
+ (url-retrieve (shr-encode-url url)
+ 'shr-store-contents (list url directory)))))
+
+(defun shr-store-contents (status url directory)
+ (unless (plist-get status :error)
+ (when (or (search-forward "\n\n" nil t)
+ (search-forward "\r\n\r\n" nil t))
+ (write-region (point) (point-max)
+ (expand-file-name (file-name-nondirectory url)
+ directory)))))
+
(defun shr-image-fetched (status buffer start end)
(when (and (buffer-name buffer)
(not (plist-get status :error)))
(defun shr-tag-s (cont)
(shr-fontize-cont cont 'strike-through))
+(defun shr-tag-span (cont)
+ (let ((start (point))
+ (color (cdr (assq 'color (shr-parse-style (cdr (assq :style cont)))))))
+ (shr-generic cont)
+ (when color
+ (let ((overlay (make-overlay start (point))))
+ (overlay-put overlay 'face (cons 'foreground-color color))))))
+
+(defun shr-parse-style (style)
+ (when style
+ (let ((plist nil))
+ (dolist (elem (split-string style ";"))
+ (when elem
+ (setq elem (split-string elem ":"))
+ (when (and (car elem)
+ (cadr elem))
+ (let ((name (replace-regexp-in-string "^ +\\| +$" "" (car elem)))
+ (value (replace-regexp-in-string "^ +\\| +$" "" (cadr elem))))
+ (push (cons (intern name obarray)
+ value)
+ plist)))))
+ plist)))
+
(defun shr-tag-a (cont)
(let ((url (cdr (assq :href cont)))
(start (point))
(setq cont (or (cdr (assq 'tbody cont))
cont))
(let* ((shr-inhibit-images t)
+ (shr-kinsoku-shorten t)
;; Find all suggested widths.
(columns (shr-column-specs cont))
;; Compute how many characters wide each TD should be.
(sketch (shr-make-table cont suggested-widths))
(sketch-widths (shr-table-widths sketch suggested-widths)))
;; This probably won't work very well.
- (when (> (1+ (loop for width across sketch-widths
- summing (1+ width)))
+ (when (> (+ (loop for width across sketch-widths
+ summing (1+ width))
+ shr-indentation 1)
(frame-width))
(setq truncate-lines t))
;; Then render the table again with these new "hard" widths.
;; possibly.
(dotimes (i (- height (length lines)))
(end-of-line)
- (insert (make-string (length (car lines)) ? ) "|")
+ (insert (make-string (string-width (car lines)) ? ) "|")
(forward-line 1)))))
(shr-insert-table-ruler widths)))
(defun shr-insert-table-ruler (widths)
- (shr-indent)
+ (when (and (bolp)
+ (> shr-indentation 0))
+ (shr-indent))
(insert shr-table-corner)
(dotimes (i (length widths))
(insert (make-string (aref widths i) shr-table-line) shr-table-corner))