* gnus-art.el (gnus-use-idna)
[gnus] / lisp / gnus-art.el
index a2d34e6..474830c 100644 (file)
@@ -2335,9 +2335,9 @@ long lines iff arg is positive."
 (eval-when-compile
   (defvar gnus-face-properties-alist))
 
-(defun article-display-face ()
+(defun article-display-face (&optional force)
   "Display any Face headers in the header."
-  (interactive)
+  (interactive (list 'force))
   (let ((wash-face-p buffer-read-only))
     (gnus-with-article-headers
       ;; When displaying parts, this function can be called several times on
@@ -2347,7 +2347,8 @@ long lines iff arg is positive."
       ;; read-only.
       (if (and wash-face-p (memq 'face gnus-article-wash-types))
          (gnus-delete-images 'face)
-       (let (face faces from)
+       (let ((from (message-fetch-field "from"))
+             face faces)
          (save-current-buffer
            (when (and wash-face-p
                       (gnus-buffer-live-p gnus-original-article-buffer)
@@ -2355,16 +2356,22 @@ long lines iff arg is positive."
              (set-buffer gnus-original-article-buffer))
            (save-restriction
              (mail-narrow-to-head)
-             (while (gnus-article-goto-header "Face")
-               (push (mail-header-field-value) faces))))
+             (when (or force
+                       ;; Check whether this face is censored.
+                       (not (and gnus-article-x-face-too-ugly
+                                 (or from
+                                     (setq from (message-fetch-field "from")))
+                                 (string-match gnus-article-x-face-too-ugly
+                                               from))))
+               (while (gnus-article-goto-header "Face")
+                 (push (mail-header-field-value) faces)))))
          (when faces
            (goto-char (point-min))
-           (let ((from (gnus-article-goto-header "from"))
-                 png image)
-             (unless from
+           (let (png image)
+             (unless (setq from (gnus-article-goto-header "from"))
                (insert "From:")
                (setq from (point))
-               (insert "[no `from' set]\n"))
+               (insert " [no `from' set]\n"))
              (while faces
                (when (setq png (gnus-convert-face-to-png (pop faces)))
                  (setq image
@@ -2389,7 +2396,8 @@ long lines iff arg is positive."
          ;; instead.
          (gnus-delete-images 'xface)
        ;; Display X-Faces.
-       (let (x-faces from face)
+       (let ((from (message-fetch-field "from"))
+             x-faces face)
          (save-current-buffer
            (when (and wash-face-p
                       (gnus-buffer-live-p gnus-original-article-buffer)
@@ -2400,43 +2408,41 @@ long lines iff arg is positive."
              (set-buffer gnus-original-article-buffer))
            (save-restriction
              (mail-narrow-to-head)
-             (while (gnus-article-goto-header "X-Face")
-               (push (mail-header-field-value) x-faces))
-             (setq from (message-fetch-field "from"))))
-         ;; Sending multiple EOFs to xv doesn't work, so we only do a
-         ;; single external face.
-         (when (stringp gnus-article-x-face-command)
-           (setq x-faces (list (car x-faces))))
-         (when (and x-faces
-                    gnus-article-x-face-command
-                    (or force
-                        ;; Check whether this face is censored.
-                        (not gnus-article-x-face-too-ugly)
-                        (and from
-                             (not (string-match gnus-article-x-face-too-ugly
-                                                from)))))
-           (while (setq face (pop x-faces))
-             ;; We display the face.
-             (cond ((stringp gnus-article-x-face-command)
-                    ;; The command is a string, so we interpret the command
-                    ;; as a, well, command, and fork it off.
-                    (let ((process-connection-type nil))
-                      (gnus-set-process-query-on-exit-flag
-                       (start-process
-                        "article-x-face" nil shell-file-name
-                        shell-command-switch gnus-article-x-face-command)
-                       nil)
-                      (with-temp-buffer
-                        (insert face)
-                        (process-send-region "article-x-face"
-                                             (point-min) (point-max)))
-                      (process-send-eof "article-x-face")))
-                   ((functionp gnus-article-x-face-command)
-                    ;; The command is a lisp function, so we call it.
-                    (funcall gnus-article-x-face-command face))
-                   (t
-                    (error "%s is not a function"
-                           gnus-article-x-face-command))))))))))
+             (and gnus-article-x-face-command
+                  (or force
+                      ;; Check whether this face is censored.
+                      (not (and gnus-article-x-face-too-ugly
+                                (or from
+                                    (setq from (message-fetch-field "from")))
+                                (string-match gnus-article-x-face-too-ugly
+                                              from))))
+                  (while (gnus-article-goto-header "X-Face")
+                    (push (mail-header-field-value) x-faces)))))
+         (when x-faces
+           ;; We display the face.
+           (cond ((functionp gnus-article-x-face-command)
+                  ;; The command is a lisp function, so we call it.
+                  (mapc gnus-article-x-face-command x-faces))
+                 ((stringp gnus-article-x-face-command)
+                  ;; The command is a string, so we interpret the command
+                  ;; as a, well, command, and fork it off.
+                  (let ((process-connection-type nil))
+                    (gnus-set-process-query-on-exit-flag
+                     (start-process
+                      "article-x-face" nil shell-file-name
+                      shell-command-switch gnus-article-x-face-command)
+                     nil)
+                    ;; Sending multiple EOFs to xv doesn't work,
+                    ;; so we only do a single external face.
+                    (with-temp-buffer
+                      (insert (car x-faces))
+                      (process-send-region "article-x-face"
+                                           (point-min) (point-max)))
+                    (process-send-eof "article-x-face")))
+                 (t
+                  (error "`%s' set to `%s' is not a function"
+                         gnus-article-x-face-command
+                         'gnus-article-x-face-command)))))))))
 
 (defun article-decode-mime-words ()
   "Decode all MIME-encoded words in the article."
@@ -2797,8 +2803,37 @@ Recurse into multiparts."
                    (string-match "text/html" (car (mm-handle-type handle))))
               (let ((tmp-file (mm-make-temp-file
                                ;; Do we need to care for 8.3 filenames?
-                               "mm-" nil ".html")))
-                (mm-save-part-to-file handle tmp-file)
+                               "mm-" nil ".html"))
+                    (charset (mail-content-type-get (mm-handle-type handle)
+                                                    'charset)))
+                (if charset
+                    ;; Add a meta html tag to specify charset.
+                    (mm-with-unibyte-buffer
+                      (insert (with-current-buffer (mm-handle-buffer handle)
+                                (if (eq charset 'gnus-decoded)
+                                    (mm-encode-coding-string
+                                     (buffer-string)
+                                     (setq charset 'utf-8))
+                                  (buffer-string))))
+                      (setq charset (format "\
+<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">"
+                                            charset))
+                      (goto-char (point-min))
+                      (let ((case-fold-search t))
+                        (cond (;; Don't modify existing meta tag.
+                               (re-search-forward "\
+<meta[\t\n\r ]+http-equiv=\"content-type\"[^>]+>"
+                                                  nil t))
+                              ((re-search-forward "<head>[\t\n\r ]*" nil t)
+                               (insert charset "\n"))
+                              (t
+                               (re-search-forward "\
+<html\\(?:[\t\n\r ]+[^>]+\\|[\t\n\r ]*\\)>[\t\n\r ]*"
+                                                  nil t)
+                               (insert "<head>\n" charset "\n</head>\n"))))
+                      (mm-write-region (point-min) (point-max)
+                                       tmp-file nil nil nil 'binary t))
+                  (mm-save-part-to-file handle tmp-file))
                 (add-to-list 'gnus-article-browse-html-temp-list tmp-file)
                 (add-hook 'gnus-summary-prepare-exit-hook
                           'gnus-article-browse-delete-temp-files)
@@ -2824,7 +2859,10 @@ Warning: Spammers use links to images in HTML articles to verify
 whether you have read the message.  As
 `gnus-article-browse-html-article' passes the unmodified HTML
 content to the browser without eliminating these \"web bugs\" you
-should only use it for mails from trusted senders."
+should only use it for mails from trusted senders.
+
+If you alwasy want to display HTML part in the browser, set
+`mm-text-html-renderer' to nil."
   ;; Cf. `mm-w3m-safe-url-regexp'
   (interactive)
   (save-window-excursion
@@ -5893,10 +5931,16 @@ If end of article, return non-nil.  Otherwise return nil.
 Argument LINES specifies lines to be scrolled up."
   (interactive "p")
   (move-to-window-line -1)
-  (if (save-excursion
-       (end-of-line)
-       (and (pos-visible-in-window-p)  ;Not continuation line.
-            (>= (1+ (point)) (point-max)))) ;Allow for trailing newline.
+  (if (and (not (and gnus-article-over-scroll
+                    (> (count-lines (window-start) (point-max))
+                       (+ (or lines (1- (window-height)))
+                          (or (and (boundp 'scroll-margin)
+                                   (symbol-value 'scroll-margin))
+                              0)))))
+          (save-excursion
+            (end-of-line)
+            (and (pos-visible-in-window-p)     ;Not continuation line.
+                 (>= (1+ (point)) (point-max))))) ;Allow for trailing newline.
       ;; Nothing in this page.
       (if (or (not gnus-page-broken)
              (save-excursion
@@ -5956,7 +6000,14 @@ Argument LINES specifies lines to be scrolled down."
       (progn
        (gnus-narrow-to-page -1)        ;Go to previous page.
        (goto-char (point-max))
-       (recenter -1))
+       (recenter (if gnus-article-over-scroll
+                     (if lines
+                         (max (+ lines (or (and (boundp 'scroll-margin)
+                                                (symbol-value 'scroll-margin))
+                                           0))
+                              3)
+                       (- (window-height) 2))
+                   -1)))
     (prog1
        (condition-case ()
            (let ((scroll-in-place nil))
@@ -7181,6 +7232,7 @@ variable it the real callback function."
                       (repeat :tag "Par"
                               :inline t
                               (integer :tag "Regexp group")))))
+(put 'gnus-button-alist 'risky-local-variable t)
 
 (defcustom gnus-header-button-alist
   '(("^\\(References\\|Message-I[Dd]\\|^In-Reply-To\\):" "<[^<>]+>"
@@ -7220,6 +7272,7 @@ HEADER is a regexp to match a header.  For a fuller explanation, see
                       (repeat :tag "Par"
                               :inline t
                               (integer :tag "Regexp group")))))
+(put 'gnus-header-button-alist 'risky-local-variable t)
 
 ;;; Commands: