X-Git-Url: https://cgit.sxemacs.org/?a=blobdiff_plain;f=lisp%2Fshr.el;h=7af1945f96c33a386d4b439957e65550d61dcab8;hb=020d37d88e428f34cfb6233fda1e382d25cbe464;hp=f7f9205e0c9ef26d2a1a18333970e99cb8ccccea;hpb=8d4b3338a773203ff8f9efab717225ccd0941b91;p=gnus diff --git a/lisp/shr.el b/lisp/shr.el index f7f9205e0..7af1945f9 100644 --- a/lisp/shr.el +++ b/lisp/shr.el @@ -51,6 +51,9 @@ fit these criteria." :type 'regexp) (defvar shr-folding-mode nil) +(defvar shr-state nil) +(defvar shr-start nil) +(defvar shr-indentation 0) (defvar shr-width 70) @@ -68,10 +71,12 @@ fit these criteria." ;;;###autoload (defun shr-insert-document (dom) - (shr-descend (shr-transform-dom dom))) + (let ((shr-state nil) + (shr-start nil)) + (shr-descend (shr-transform-dom dom)))) (defun shr-descend (dom) - (let ((function (intern (concat "shr-" (symbol-name (car dom))) obarray))) + (let ((function (intern (concat "shr-tag-" (symbol-name (car dom))) obarray))) (if (fboundp function) (funcall function (cdr dom)) (shr-generic (cdr dom))))) @@ -81,41 +86,43 @@ fit these criteria." (cond ((eq (car sub) :text) (shr-insert (cdr sub))) - ((consp (cdr sub)) + ((listp (cdr sub)) (shr-descend sub))))) -(defun shr-p (cont) - (shr-ensure-newline) - (insert "\n") +(defun shr-tag-p (cont) + (unless (bobp) + (shr-ensure-newline) + (insert "\n")) (shr-generic cont) (insert "\n")) -(defun shr-b (cont) +(defun shr-tag-b (cont) (shr-fontize-cont cont 'bold)) -(defun shr-i (cont) +(defun shr-tag-i (cont) (shr-fontize-cont cont 'italic)) -(defun shr-u (cont) +(defun shr-tag-u (cont) (shr-fontize-cont cont 'underline)) (defun shr-s (cont) (shr-fontize-cont cont 'strikethru)) (defun shr-fontize-cont (cont type) - (let ((start (point))) + (let (shr-start) (shr-generic cont) - (shr-add-font start (point) type))) + (shr-add-font (or shr-start (point)) (point) type))) (defun shr-add-font (start end type) - (put-text-property start end 'face type)) + (let ((overlay (make-overlay start end))) + (overlay-put overlay 'face type))) -(defun shr-a (cont) - (let ((start (point)) - (url (cdr (assq :href cont)))) +(defun shr-tag-a (cont) + (let ((url (cdr (assq :href cont))) + shr-start) (shr-generic cont) (widget-convert-button - 'link start (point) + 'link shr-start (point) :action 'shr-browse-url :url url :keymap widget-keymap @@ -124,7 +131,10 @@ fit these criteria." (defun shr-browse-url (widget &rest stuff) (browse-url (widget-get widget :url))) -(defun shr-img (cont) +(defun shr-tag-img (cont) + (when (and (plusp (current-column)) + (not (eq shr-state 'image))) + (insert "\n")) (let ((start (point-marker))) (let ((alt (cdr (assq :alt cont))) (url (cdr (assq :src cont)))) @@ -134,14 +144,15 @@ fit these criteria." ((and shr-blocked-images (string-match shr-blocked-images url)) (insert alt)) - ((url-is-cached url) + ((url-is-cached (browse-url-url-encode-chars url "[&)$ ]")) (shr-put-image (shr-get-image-data url) (point) alt)) (t (insert alt) (url-retrieve url 'shr-image-fetched (list (current-buffer) start (point-marker)) t))) - (insert " ")))) + (insert " ") + (setq shr-state 'image)))) (defun shr-image-fetched (status buffer start end) (when (and (buffer-name buffer) @@ -160,15 +171,17 @@ fit these criteria." (defun shr-put-image (data point alt) (if (not (display-graphic-p)) (insert alt) - (let ((image (shr-rescale-image data))) - (put-image image point alt)))) + (let ((image (ignore-errors + (shr-rescale-image data)))) + (when image + (put-image image point alt))))) (defun shr-rescale-image (data) (if (or (not (fboundp 'imagemagick-types)) (not (get-buffer-window (current-buffer)))) (create-image data nil t) (let* ((image (create-image data nil t)) - (size (image-size image)) + (size (image-size image t)) (width (car size)) (height (cdr size)) (edges (window-inside-pixel-edges @@ -190,20 +203,24 @@ fit these criteria." image))) image))) -(defun shr-pre (cont) +(defun shr-tag-pre (cont) (let ((shr-folding-mode nil)) (shr-ensure-newline) (shr-generic cont) (shr-ensure-newline))) -(defun shr-blockquote (cont) - (shr-pre cont)) +(defun shr-tag-blockquote (cont) + (let ((shr-indentation (+ shr-indentation 4))) + (shr-tag-pre cont))) (defun shr-ensure-newline () (unless (zerop (current-column)) (insert "\n"))) (defun shr-insert (text) + (when (eq shr-state 'image) + (insert "\n") + (setq shr-state nil)) (cond ((eq shr-folding-mode 'none) (insert t)) @@ -211,11 +228,19 @@ fit these criteria." (let (column) (dolist (elem (split-string text)) (setq column (current-column)) - (if (zerop column) - (insert elem) + (when (plusp column) (if (> (+ column (length elem) 1) shr-width) - (insert "\n" elem) - (insert " " elem)))))))) + (insert "\n") + (insert " "))) + (when (and (bolp) + (plusp shr-indentation)) + (insert (make-string shr-indentation ? ))) + ;; The shr-start is a special variable that is used to pass + ;; upwards the first point in the buffer where the text really + ;; starts. + (unless shr-start + (setq shr-start (point))) + (insert elem)))))) (defun shr-get-image-data (url) "Get image data for URL. @@ -227,6 +252,29 @@ Return a string with image data." (search-forward "\r\n\r\n" nil t)) (buffer-substring (point) (point-max))))) +(defvar shr-list-mode nil) + +(defun shr-tag-ul (cont) + (let ((shr-list-mode 'ul)) + (shr-generic cont))) + +(defun shr-tag-ol (cont) + (let ((shr-list-mode 1)) + (shr-generic cont))) + +(defun shr-tag-li (cont) + (shr-ensure-newline) + (if (numberp shr-list-mode) + (progn + (insert (format "%d " shr-list-mode)) + (setq shr-list-mode (1+ shr-list-mode))) + (insert "* ")) + (shr-generic cont)) + +(defun shr-tag-br (cont) + (shr-ensure-newline) + (shr-generic cont)) + (provide 'shr) ;;; shr.el ends here