Fix comment typo.
[gnus] / lisp / shr.el
index ca7d8bf..35c4021 100644 (file)
@@ -52,10 +52,16 @@ fit these criteria."
   :group 'shr
   :type 'regexp)
 
+(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
+cid: URL as the argument.")
+
 (defvar shr-folding-mode nil)
 (defvar shr-state nil)
 (defvar shr-start nil)
 (defvar shr-indentation 0)
+(defvar shr-inhibit-images nil)
 
 (defvar shr-width 70)
 
@@ -125,6 +131,9 @@ fit these criteria."
 (defun shr-tag-i (cont)
   (shr-fontize-cont cont 'italic))
 
+(defun shr-tag-em (cont)
+  (shr-fontize-cont cont 'bold))
+
 (defun shr-tag-u (cont)
   (shr-fontize-cont cont 'underline))
 
@@ -201,16 +210,30 @@ redirects somewhere else."
       (when (zerop (length alt))
        (setq alt "[img]"))
       (cond
-       ((and shr-blocked-images
-            (string-match shr-blocked-images url))
-       (insert alt))
+       ((and (not shr-inhibit-images)
+            (string-match "\\`cid:" url))
+       (let ((url (substring url (match-end 0)))
+             image)
+         (if (or (not shr-content-function)
+                 (not (setq image (funcall shr-content-function url))))
+             (insert alt)
+           (shr-put-image image (point) alt))))
+       ((or shr-inhibit-images
+           (and shr-blocked-images
+                (string-match shr-blocked-images url)))
+       (setq shr-start (point))
+       (let ((shr-state 'space))
+         (if (> (length alt) 8)
+             (shr-insert (substring alt 0 8))
+           (shr-insert alt))))
        ((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)))
+       (ignore-errors
+         (url-retrieve url 'shr-image-fetched
+                       (list (current-buffer) start (point-marker))
+                       t))))
       (insert " ")
       (put-text-property start (point) 'keymap shr-map)
       (put-text-property start (point) 'shr-alt alt)
@@ -292,7 +315,8 @@ redirects somewhere else."
 (defun shr-tag-blockquote (cont)
   (shr-ensure-paragraph)
   (let ((shr-indentation (+ shr-indentation 4)))
-    (shr-generic cont)))
+    (shr-generic cont))
+  (shr-ensure-paragraph))
 
 (defun shr-ensure-newline ()
   (unless (zerop (current-column))
@@ -345,10 +369,12 @@ redirects somewhere else."
 Return a string with image data."
   (with-temp-buffer
     (mm-disable-multibyte)
-    (url-cache-extract (url-cache-create-filename url))
-    (when (or (search-forward "\n\n" nil t)
-              (search-forward "\r\n\r\n" nil t))
-      (buffer-substring (point) (point-max)))))
+    (when (ignore-errors
+           (url-cache-extract (url-cache-create-filename url))
+           t)
+      (when (or (search-forward "\n\n" nil t)
+               (search-forward "\r\n\r\n" nil t))
+       (buffer-substring (point) (point-max))))))
 
 (defvar shr-list-mode nil)
 
@@ -405,11 +431,23 @@ Return a string with image data."
   (shr-ensure-paragraph)
   (setq cont (or (cdr (assq 'tbody cont))
                 cont))
-  (let* ((columns (shr-column-specs cont))
+  (let* ((shr-inhibit-images t)
+        (columns (shr-column-specs cont))
         (suggested-widths (shr-pro-rate-columns columns))
         (sketch (shr-make-table cont suggested-widths))
         (sketch-widths (shr-table-widths sketch (length suggested-widths))))
-    (shr-insert-table (shr-make-table cont sketch-widths t) sketch-widths)))
+    (shr-insert-table (shr-make-table cont sketch-widths t) sketch-widths))
+  (dolist (elem (shr-find-elements cont 'img))
+    (shr-tag-img (cdr elem))))
+
+(defun shr-find-elements (cont type)
+  (let (result)
+    (dolist (elem cont)
+      (cond ((eq (car elem) type)
+            (push elem result))
+           ((consp (cdr elem))
+            (setq result (nconc (shr-find-elements (cdr elem) type) result)))))
+    (nreverse result)))
 
 (defun shr-insert-table (table widths)
   (shr-insert-table-ruler widths)
@@ -424,11 +462,20 @@ Return a string with image data."
        (insert "|\n"))
       (dolist (column row)
        (goto-char start)
-       (let ((lines (split-string (nth 2 column) "\n")))
+       (let ((lines (split-string (nth 2 column) "\n"))
+             (overlay-lines (nth 3 column))
+             overlay overlay-line)
          (dolist (line lines)
+           (setq overlay-line (pop overlay-lines))
            (when (> (length line) 0)
              (end-of-line)
              (insert line "|")
+             (dolist (overlay overlay-line)
+               (let ((o (make-overlay (- (point) (nth 0 overlay) 1)
+                                      (- (point) (nth 1 overlay) 1)))
+                     (properties (nth 2 overlay)))
+                 (while properties
+                   (overlay-put o (pop properties) (pop properties)))))
              (forward-line 1)))
          ;; Add blank lines at padding at the bottom of the TD,
          ;; possibly.
@@ -459,10 +506,14 @@ Return a string with image data."
   (let ((trs nil))
     (dolist (row cont)
       (when (eq (car row) 'tr)
-       (let ((i 0)
-             (tds nil))
-         (dolist (column (cdr row))
-           (when (memq (car column) '(td th))
+       (let ((tds nil)
+             (columns (cdr row))
+             (i 0)
+             column)
+         (while (< i (length widths))
+           (setq column (pop columns))
+           (when (or (memq (car column) '(td th))
+                     (null column))
              (push (shr-render-td (cdr column) (aref widths i) fill)
                    tds)
              (setq i (1+ i))))
@@ -484,12 +535,44 @@ Return a string with image data."
        (forward-line 1))
       (when fill
        (goto-char (point-min))
-       (while (not (eobp))
-         (end-of-line)
-         (when (> (- width (current-column)) 0)
-           (insert (make-string (- width (current-column)) ? )))
-         (forward-line 1)))
-      (list max (count-lines (point-min) (point-max)) (buffer-string)))))
+       ;; If the buffer is totally empty, then put a single blank
+       ;; line here.
+       (if (zerop (buffer-size))
+           (insert (make-string width ? ))
+         ;; Otherwise, fill the buffer.
+         (while (not (eobp))
+           (end-of-line)
+           (when (> (- width (current-column)) 0)
+             (insert (make-string (- width (current-column)) ? )))
+           (forward-line 1))))
+      (list max
+           (count-lines (point-min) (point-max))
+           (buffer-string)
+           (and fill
+                (shr-collect-overlays))))))
+
+(defun shr-collect-overlays ()
+  (save-excursion
+    (goto-char (point-min))
+    (let ((overlays nil))
+      (while (not (eobp))
+       (push (shr-overlays-in-region (point) (line-end-position))
+             overlays)
+       (forward-line 1))
+      (nreverse overlays))))
+
+(defun shr-overlays-in-region (start end)
+  (let (result)
+    (dolist (overlay (overlays-in start end))
+      (push (list (if (> start (overlay-start overlay))
+                     (- end start)
+                   (- end (overlay-start overlay)))
+                 (if (< end (overlay-end overlay))
+                     0
+                   (- end (overlay-end overlay)))
+                 (overlay-properties overlay))
+           result))
+    (nreverse result)))
 
 (defun shr-pro-rate-columns (columns)
   (let ((total-percentage 0)
@@ -517,8 +600,8 @@ Return a string with image data."
                           (string-match "\\([0-9]+\\)%" width))
                  (aset columns i
                        (/ (string-to-number (match-string 1 width))
-                          100.0)))))
-           (setq i (1+ i))))))
+                          100.0))))
+             (setq i (1+ i)))))))
     columns))
 
 (defun shr-count (cont elem)
@@ -532,7 +615,8 @@ Return a string with image data."
   (let ((max 0))
     (dolist (row cont)
       (when (eq (car row) 'tr)
-       (setq max (max max (shr-count (cdr row) 'td)))))
+       (setq max (max max (+ (shr-count (cdr row) 'td)
+                             (shr-count (cdr row) 'th))))))
     max))
 
 (provide 'shr)