2001-12-18 01:00:00 ShengHuo ZHU <zsh@cs.rochester.edu>
[gnus] / lisp / gnus-art.el
index 4004119..1b3cf01 100644 (file)
     "^X-Received:" "^Content-length:" "X-precedence:"
     "^X-Authenticated-User:" "^X-Comment" "^X-Report:" "^X-Abuse-Info:"
     "^X-HTTP-Proxy:" "^X-Mydeja-Info:" "^X-Copyright" "^X-No-Markup:"
-    "^X-Abuse-Info:")
+    "^X-Abuse-Info:" "^X-From_:" "^X-Accept-Language:" "^Errors-To:"
+    "^X-BeenThere:" "^X-Mailman-Version:" "^List-Help:" "^List-Post:"
+    "^List-Subscribe:" "^List-Id:" "^List-Unsubscribe:" "^List-Archive:"
+     "^X-Content-length:" "^X-Posting-Agent:" "^Original-Received:")
   "*All headers that start with this regexp will be hidden.
 This variable can also be a list of regexps of headers to be ignored.
 If `gnus-visible-headers' is non-nil, this variable will be ignored."
@@ -217,20 +220,27 @@ regexp.  If it matches, the text in question is not a signature."
 
 ;; Fixme: This isn't the right thing for mixed graphical and and
 ;; non-graphical frames in a session.
-;; gnus-xmas.el overrides this for XEmacs.
 (defcustom gnus-article-x-face-command
-  (if (and (fboundp 'image-type-available-p)
-          (image-type-available-p 'xbm))
-      'gnus-article-display-xface
-    (if gnus-article-compface-xbm
-       "{ echo '/* Width=48, Height=48 */'; uncompface; } | display -"
-      "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | \
-display -"))
+  (if (featurep 'xemacs)
+      (if (or (featurep 'xface)
+             (featurep 'xpm))
+         'gnus-xmas-article-display-xface
+       "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | ee -")
+    (if (and (fboundp 'image-type-available-p)
+            (image-type-available-p 'xbm))
+       'gnus-article-display-xface
+      (if gnus-article-compface-xbm
+         "{ echo '/* Width=48, Height=48 */'; uncompface; } | display -"
+       "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | \
+display -")))
   "*String or function to be executed to display an X-Face header.
 If it is a string, the command will be executed in a sub-shell
 asynchronously.         The compressed face will be piped to this command."
-  :type '(choice string
-                (function-item gnus-article-display-xface)
+  :type `(choice string
+                (function-item 
+                 ,(if (featurep 'xemacs)
+                      'gnus-xmas-article-display-xface
+                    'gnus-article-display-xface))
                 function)
   :version "21.1"
   :group 'gnus-article-washing)
@@ -400,6 +410,7 @@ Gnus provides the following functions:
 * gnus-summary-save-in-mail (Unix mail format)
 * gnus-summary-save-in-folder (MH folder)
 * gnus-summary-save-in-file (article format)
+* gnus-summary-save-body-in-file (article body)
 * gnus-summary-save-in-vm (use VM's folder format)
 * gnus-summary-write-to-file (article format -- overwrite)."
   :group 'gnus-article-saving
@@ -407,6 +418,7 @@ Gnus provides the following functions:
                (function-item gnus-summary-save-in-mail)
                (function-item gnus-summary-save-in-folder)
                (function-item gnus-summary-save-in-file)
+               (function-item gnus-summary-save-body-in-file)
                (function-item gnus-summary-save-in-vm)
                (function-item gnus-summary-write-to-file)))
 
@@ -628,7 +640,8 @@ displayed by the first non-nil matching CONTENT face."
                               (face :value default)))))
 
 (defcustom gnus-article-decode-hook
-  '(article-decode-charset article-decode-encoded-words)
+  '(article-decode-charset article-decode-encoded-words
+                          article-decode-group-name)
   "*Hook run to decode charsets in articles."
   :group 'gnus-article-headers
   :type 'hook)
@@ -669,7 +682,17 @@ displayed by the first non-nil matching CONTENT face."
   :type '(repeat regexp))
 
 (defcustom gnus-unbuttonized-mime-types '(".*/.*")
-  "List of MIME types that should not be given buttons when rendered inline."
+  "List of MIME types that should not be given buttons when rendered inline.
+See also `gnus-buttonized-mime-types' which may override this variable."
+  :version "21.1"
+  :group 'gnus-article-mime
+  :type '(repeat regexp))
+
+(defcustom gnus-buttonized-mime-types nil
+  "List of MIME types that should be given buttons when rendered inline.
+If set, this variable overrides `gnus-unbuttonized-mime-types'.
+To see e.g. security buttons you could set this to
+`(\"multipart/signed\")'."
   :version "21.1"
   :group 'gnus-article-mime
   :type '(repeat regexp))
@@ -773,7 +796,7 @@ used."
 (defcustom gnus-treat-highlight-signature '(or last (typep "text/x-vcard"))
   "Highlight the signature.
 Valid values are nil, t, `head', `last', an integer or a predicate.
-See the manual for details."
+See Info node `(gnus)Customizing Articles'."
   :group 'gnus-article-treat
   :type gnus-article-treat-custom)
 (put 'gnus-treat-highlight-signature 'highlight t)
@@ -862,13 +885,6 @@ See the manual for details."
   :group 'gnus-article-treat
   :type gnus-article-treat-custom)
 
-(defcustom gnus-treat-hide-citation-maybe nil
-  "Hide cited text.
-Valid values are nil, t, `head', `last', an integer or a predicate.
-See the manual for details."
-  :group 'gnus-article-treat
-  :type gnus-article-treat-custom)
-
 (defcustom gnus-treat-strip-list-identifiers 'head
   "Strip list identifiers from `gnus-list-identifiers`.
 Valid values are nil, t, `head', `last', an integer or a predicate.
@@ -1644,7 +1660,8 @@ MAP is an alist where the elements are on the form (\"from\" \"to\")."
          ;; We now have the area of the buffer where the X-Face is stored.
          (save-excursion
            (let ((beg (point))
-                 (end (1- (re-search-forward "^\\($\\|[^ \t]\\)" nil t))))
+                 (end (1- (re-search-forward "^\\($\\|[^ \t]\\)" nil t)))
+                 buffer-read-only)
              ;; We display the face.
              (if (symbolp gnus-article-x-face-command)
                  ;; The command is a lisp function, so we call it.
@@ -1734,6 +1751,29 @@ If PROMPT (the prefix), prompt for a coding system to use."
       (article-narrow-to-head)
       (funcall gnus-decode-header-function (point-min) (point-max)))))
 
+(defun article-decode-group-name ()
+  "Decode group names in `Newsgroups:'."
+  (let ((inhibit-point-motion-hooks t)
+       buffer-read-only
+       (method (gnus-find-method-for-group gnus-newsgroup-name)))
+    (when (and (or gnus-group-name-charset-method-alist
+                  gnus-group-name-charset-group-alist)
+              (gnus-buffer-live-p gnus-original-article-buffer))
+      (when (nnmail-fetch-field "Newsgroups")
+       (nnheader-replace-header "Newsgroups"
+                                (gnus-decode-newsgroups
+                                 (with-current-buffer
+                                     gnus-original-article-buffer
+                                   (nnmail-fetch-field "Newsgroups"))
+                                 gnus-newsgroup-name method)))
+      (when (nnmail-fetch-field "Followup-To")
+       (nnheader-replace-header "Followup-To"
+                                (gnus-decode-newsgroups
+                                 (with-current-buffer
+                                     gnus-original-article-buffer
+                                   (nnmail-fetch-field "Followup-To"))
+                                 gnus-newsgroup-name method))))))
+
 (defun article-de-quoted-unreadable (&optional force read-charset)
   "Translate a quoted-printable-encoded article.
 If FORCE, decode the article whether it is marked as quoted-printable
@@ -2466,13 +2506,13 @@ This format is defined by the `gnus-article-time-format' variable."
                face (nth 3 elem))
          (while (re-search-forward regexp nil t)
            (when (and (match-beginning visible) (match-beginning invisible))
-             (push 'emphasis gnus-article-wash-types)
              (gnus-article-hide-text
               (match-beginning invisible) (match-end invisible) props)
              (gnus-article-unhide-text-type
               (match-beginning visible) (match-end visible) 'emphasis)
              (gnus-put-text-property-excluding-newlines
               (match-beginning visible) (match-end visible) 'face face)
+             (push 'emphasis gnus-article-wash-types)
              (goto-char (match-end invisible)))))))))
 
 (defun gnus-article-setup-highlight-words (&optional highlight-words)
@@ -2674,7 +2714,7 @@ Directory to save to is default to `gnus-article-save-directory'."
   filename)
 
 (defun gnus-summary-write-to-file (&optional filename)
-  "Write this article to a file.
+  "Write this article to a file, overwriting it if the file exists.
 Optional argument FILENAME specifies file name.
 The directory to save in defaults to `gnus-article-save-directory'."
   (gnus-summary-save-in-file nil t))
@@ -2723,6 +2763,13 @@ The directory to save in defaults to `gnus-article-save-directory'."
       (shell-command-on-region (point-min) (point-max) command nil)))
   (setq gnus-last-shell-command command))
 
+(defun gnus-summary-pipe-to-muttprint (&optional command)
+  "Pipe this article to muttprint."
+  (setq command (read-string
+                "Print using command: " gnus-summary-muttprint-program
+                nil gnus-summary-muttprint-program))
+  (gnus-summary-save-in-pipe command))
+
 ;;; Article file names when saving.
 
 (defun gnus-capitalize-newsgroup (newsgroup)
@@ -2862,6 +2909,12 @@ If variable `gnus-use-long-file-name' is non-nil, it is
                  (put-text-property (match-end 0) (point-max)
                                     'face eface)))))))))
 
+(defun article-verify-cancel-lock ()
+  "Verify Cancel-Lock header."
+  (interactive)
+  (if (gnus-buffer-live-p gnus-original-article-buffer)
+      (canlock-verify gnus-original-article-buffer)))
+
 (eval-and-compile
   (mapcar
    (lambda (func)
@@ -2883,6 +2936,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is
                  (apply ',afunc args))))))))
    '(article-hide-headers
      article-verify-x-pgp-sig
+     article-verify-cancel-lock
      article-hide-boring-headers
      article-treat-overstrike
      article-fill-long-lines
@@ -3694,12 +3748,9 @@ If no internal viewer is available, use an external viewer."
 
 (defun gnus-insert-mime-button (handle gnus-tmp-id &optional displayed)
   (let ((gnus-tmp-name
-        (or (mail-content-type-get (mm-handle-type handle)
-                                   'name)
-            (mail-content-type-get (mm-handle-disposition handle)
-                                   'filename)
-            (mail-content-type-get (mm-handle-type handle)
-                                   'url)
+        (or (mail-content-type-get (mm-handle-type handle) 'name)
+            (mail-content-type-get (mm-handle-disposition handle) 'filename)
+            (mail-content-type-get (mm-handle-type handle) 'url)
             ""))
        (gnus-tmp-type (mm-handle-media-type handle))
        (gnus-tmp-description
@@ -3717,8 +3768,8 @@ If no internal viewer is available, use an external viewer."
     (setq gnus-tmp-type-long (concat gnus-tmp-type
                                     (and (not (equal gnus-tmp-name ""))
                                          (concat "; " gnus-tmp-name))))
-    (or (equal gnus-tmp-description "")
-       (setq gnus-tmp-type-long (concat " --- " gnus-tmp-type-long)))
+    (unless (equal gnus-tmp-description "")
+      (setq gnus-tmp-type-long (concat " --- " gnus-tmp-type-long)))
     (unless (bolp)
       (insert "\n"))
     (setq b (point))
@@ -3934,11 +3985,16 @@ If no internal viewer is available, use an external viewer."
 (defun gnus-unbuttonized-mime-type-p (type)
   "Say whether TYPE is to be unbuttonized."
   (unless gnus-inhibit-mime-unbuttonizing
-    (catch 'found
-      (let ((types gnus-unbuttonized-mime-types))
-       (while types
-         (when (string-match (pop types) type)
-           (throw 'found t)))))))
+    (when (catch 'found
+           (let ((types gnus-unbuttonized-mime-types))
+             (while types
+               (when (string-match (pop types) type)
+                 (throw 'found t)))))
+      (not (catch 'found
+            (let ((types gnus-buttonized-mime-types))
+              (while types
+                (when (string-match (pop types) type)
+                  (throw 'found t)))))))))
 
 (defun gnus-article-insert-newline ()
   "Insert a newline, but mark it as undeletable."
@@ -4042,6 +4098,39 @@ If no internal viewer is available, use an external viewer."
     (when ibegend
       (goto-char point))))
 
+(defconst gnus-article-wash-status-strings
+  (let ((alist '((cite "c" "Possible hidden citation text" 
+                      " " "All citation text visible")
+                (headers "h" "Hidden headers"
+                         " " "All headers visible.")
+                (pgp "p" "Encrypted or signed message status hidden" 
+                     " " "No hidden encryption nor digital signature status")
+                (signature "s" "Signature has been hidden"
+                           " " "Signature is visible")
+                (overstrike "o" "Overstrike (^H) characters applied"
+                            " " "No overstrike characters applied")
+                (emphasis "e" "/*_Emphasis_*/ characters applied"
+                          " " "No /*_emphasis_*/ characters applied")))
+       result)
+    (dolist (entry alist result)
+      (let ((key (nth 0 entry))
+           (on (copy-sequence (nth 1 entry)))
+           (on-help (nth 2 entry))
+           (off (copy-sequence (nth 3 entry)))
+           (off-help (nth 4 entry)))
+       (put-text-property 0 1 'help-echo on-help on)
+       (put-text-property 0 1 'help-echo off-help off)
+       (push (list key on off) result))))
+  "Alist of strings describing wash status in the mode line.
+Each entry has the form (KEY ON OF), where the KEY is a symbol
+representing the particular washing function, ON is the string to use
+in the article mode line when the washing function is active, and OFF
+is the string to use when it is inactive.")
+      
+(defun gnus-gnus-article-wash-status-entry (key value)
+  (let ((entry (assoc key gnus-article-wash-status-strings)))
+    (if value (nth 1 entry) (nth 2 entry))))
+
 (defun gnus-article-wash-status ()
   "Return a string which display status of article washing."
   (save-excursion
@@ -4056,13 +4145,14 @@ If no internal viewer is available, use an external viewer."
          (signature (memq 'signature gnus-article-wash-types))
          (overstrike (memq 'overstrike gnus-article-wash-types))
          (emphasis (memq 'emphasis gnus-article-wash-types)))
-      (format "%c%c%c%c%c%c"
-             (if cite ?c ? )
-             (if (or headers boring) ?h ? )
-             (if (or pgp pem signed encrypted) ?p ? )
-             (if signature ?s ? )
-             (if overstrike ?o ? )
-             (if emphasis ?e ? )))))
+      (concat (gnus-gnus-article-wash-status-entry 'cite cite)
+             (gnus-gnus-article-wash-status-entry 'headers 
+                                                  (or headers boring))
+             (gnus-gnus-article-wash-status-entry 
+              'pgp (or pgp pem signed encrypted))
+             (gnus-gnus-article-wash-status-entry 'signature signature)
+             (gnus-gnus-article-wash-status-entry 'overstrike overstrike)
+             (gnus-gnus-article-wash-status-entry 'emphasis emphasis)))))
 
 (defalias 'gnus-article-hide-headers-if-wanted 'gnus-article-maybe-hide-headers)
 
@@ -4086,7 +4176,8 @@ Provided for backwards compatibility."
       ;; save it to file.
       (goto-char (point-max))
       (insert "\n")
-      (mm-append-to-file (point-min) (point-max) file-name)
+      (let ((file-name-coding-system nnmail-pathname-coding-system))
+       (mm-append-to-file (point-min) (point-max) file-name))
       t)))
 
 (defun gnus-narrow-to-page (&optional arg)
@@ -4495,7 +4586,9 @@ If given a prefix, show the hidden text instead."
                (setq gnus-override-method (pop methods)))
              (while (not result)
                (when (eq gnus-override-method 'current)
-                 (setq gnus-override-method gnus-current-select-method))
+                 (setq gnus-override-method
+                       (with-current-buffer gnus-summary-buffer
+                         gnus-current-select-method)))
                (erase-buffer)
                (gnus-kill-all-overlays)
                (let ((gnus-newsgroup-name group))
@@ -4699,7 +4792,7 @@ groups."
 
 ;;; Internal Variables:
 
-(defcustom gnus-button-url-regexp "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\):\\)\\(//[-a-zA-Z0-9_.]+:[0-9]*\\)?\\([-a-zA-Z0-9_=!?#$@~`%&*+|\\/:;.,]\\|\\w\\)+\\([-a-zA-Z0-9_=#$@~`%&*+|\\/]\\|\\w\\)\\)"
+(defcustom gnus-button-url-regexp "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\|info\\):\\)\\(//[-a-zA-Z0-9_.]+:[0-9]*\\)?\\([-a-zA-Z0-9_=!?#$@~`%&*+|\\/:;.,]\\|\\w\\)+\\([-a-zA-Z0-9_=#$@~`%&*+|\\/]\\|\\w\\)\\)"
   "Regular expression that matches URLs."
   :group 'gnus-article-buttons
   :type 'regexp)
@@ -4718,6 +4811,9 @@ groups."
     ("\\(<URL: *\\)mailto: *\\([^> \n\t]+\\)>" 0 t gnus-url-mailto 2)
     ("mailto:\\([-a-zA-Z.@_+0-9%=?]+\\)" 0 t gnus-url-mailto 1)
     ("\\bmailto:\\([^ \n\t]+\\)" 0 t gnus-url-mailto 1)
+    ;; This is info
+    ("\\binfo:\\(//\\)?\\([^'\">\n\t ]+\\)" 0 t
+     gnus-button-handle-info 2)
     ;; This is how URLs _should_ be embedded in text...
     ("<URL: *\\([^<>]*\\)>" 0 t gnus-button-embedded-url 1)
     ;; Raw URLs.
@@ -5006,14 +5102,21 @@ specified by `gnus-button-alist'."
     (let ((buffer-read-only nil)
          (inhibit-point-motion-hooks t))
       (if (text-property-any end (point-max) 'article-type 'signature)
-         (gnus-remove-text-properties-when
-          'article-type 'signature end (point-max)
-          (cons 'article-type (cons 'signature
-                                    gnus-hidden-properties)))
+         (progn
+           (setq gnus-article-wash-types
+                 (delq 'signature gnus-article-wash-types))
+           (gnus-remove-text-properties-when
+            'article-type 'signature end (point-max)
+            (cons 'article-type (cons 'signature
+                                      gnus-hidden-properties))))
+       (or (memq 'signature gnus-article-wash-types)
+           (push 'signature gnus-article-wash-types))
        (gnus-add-text-properties-when
         'article-type nil end (point-max)
         (cons 'article-type (cons 'signature
-                                  gnus-hidden-properties)))))))
+                                  gnus-hidden-properties)))))
+    (let ((gnus-article-mime-handle-alist-1 gnus-article-mime-handle-alist))
+      (gnus-set-mode-line 'article))))
 
 (defun gnus-button-entry ()
   ;; Return the first entry in `gnus-button-alist' matching this place.
@@ -5088,6 +5191,18 @@ specified by `gnus-button-alist'."
      (group
       (gnus-button-fetch-group url)))))
 
+(defun gnus-button-handle-info (url)
+  "Fetch an info URL."
+  (if (string-match 
+       "^\\([^:/]+\\)?/\\(.*\\)"
+       url)
+      (gnus-info-find-node
+       (concat "(" (or (gnus-url-unhex-string (match-string 1 url))
+                      "Gnus") 
+              ")" 
+              (gnus-url-unhex-string (match-string 2 url))))
+    (error "Can't parse %s" url)))
+
 (defun gnus-button-message-id (message-id)
   "Fetch MESSAGE-ID."
   (save-excursion
@@ -5132,38 +5247,6 @@ specified by `gnus-button-alist'."
          (setq retval (cons (list key val) retval)))))
     retval))
 
-(defun gnus-url-unhex (x)
-  (if (> x ?9)
-      (if (>= x ?a)
-         (+ 10 (- x ?a))
-       (+ 10 (- x ?A)))
-    (- x ?0)))
-
-(defun gnus-url-unhex-string (str &optional allow-newlines)
-  "Remove %XXX embedded spaces, etc in a url.
-If optional second argument ALLOW-NEWLINES is non-nil, then allow the
-decoding of carriage returns and line feeds in the string, which is normally
-forbidden in URL encoding."
-  (setq str (or str ""))
-  (let ((tmp "")
-       (case-fold-search t))
-    (while (string-match "%[0-9a-f][0-9a-f]" str)
-      (let* ((start (match-beginning 0))
-            (ch1 (gnus-url-unhex (elt str (+ start 1))))
-            (code (+ (* 16 ch1)
-                     (gnus-url-unhex (elt str (+ start 2))))))
-       (setq tmp (concat
-                  tmp (substring str 0 start)
-                  (cond
-                   (allow-newlines
-                    (char-to-string code))
-                   ((or (= code ?\n) (= code ?\r))
-                    " ")
-                   (t (char-to-string code))))
-             str (substring str (match-end 0)))))
-    (setq tmp (concat tmp str))
-    tmp))
-
 (defun gnus-url-mailto (url)
   ;; Send mail to someone
   (when (string-match "mailto:/*\\(.*\\)" url)
@@ -5481,21 +5564,25 @@ For example:
 (defun gnus-mime-security-verify-or-decrypt (handle)
   (mm-remove-parts (cdr handle))
   (let ((region (mm-handle-multipart-ctl-parameter handle 'gnus-region))
-       buffer-read-only)
+       point buffer-read-only)
+    (if region
+       (goto-char (car region)))
+    (save-restriction
+      (narrow-to-region (point) (point))
+      (with-current-buffer (mm-handle-multipart-original-buffer handle)
+       (let* ((mm-verify-option 'known)
+              (mm-decrypt-option 'known)
+              (nparts (mm-possibly-verify-or-decrypt (cdr handle) handle)))
+         (unless (eq nparts (cdr handle))
+           (mm-destroy-parts (cdr handle))
+           (setcdr handle nparts))))
+      (setq point (point))
+      (gnus-mime-display-security handle)
+      (goto-char (point-max)))
     (when region
-      (delete-region (car region) (cdr region))
+      (delete-region (point) (cdr region))
       (set-marker (car region) nil)
-      (set-marker (cdr region) nil)))
-  (with-current-buffer (mm-handle-multipart-original-buffer handle)
-    (let* ((mm-verify-option 'known)
-          (mm-decrypt-option 'known)
-          (nparts (mm-possibly-verify-or-decrypt (cdr handle) handle)))
-      (unless (eq nparts (cdr handle))
-       (mm-destroy-parts (cdr handle))
-       (setcdr handle nparts))))
-  (let ((point (point))
-       buffer-read-only)
-    (gnus-mime-display-security handle)
+      (set-marker (cdr region) nil))
     (goto-char point)))
 
 (defun gnus-mime-security-show-details (handle)
@@ -5511,13 +5598,15 @@ For example:
                         gnus-mime-security-button-line-format)
                (forward-char -1))
              (forward-char)
+             (save-restriction
+               (narrow-to-region (point) (point))
+               (gnus-insert-mime-security-button handle))
              (delete-region (point)
                             (or (text-property-not-all
                                  (point) (point-max)
-                               'gnus-line-format
-                               gnus-mime-security-button-line-format)
-                                (point-max)))
-             (gnus-insert-mime-security-button handle))
+                                 'gnus-line-format
+                                 gnus-mime-security-button-line-format)
+                                (point-max))))
          (if (gnus-buffer-live-p gnus-mime-security-details-buffer)
              (with-current-buffer gnus-mime-security-details-buffer
                (erase-buffer)
@@ -5590,13 +5679,15 @@ For example:
 (defun gnus-mime-display-security (handle)
   (save-restriction
     (narrow-to-region (point) (point))
-    (gnus-insert-mime-security-button handle)
+    (unless (gnus-unbuttonized-mime-type-p (car handle))
+      (gnus-insert-mime-security-button handle))
     (gnus-mime-display-mixed (cdr handle))
     (unless (bolp)
       (insert "\n"))
-    (let ((gnus-mime-security-button-line-format
-          gnus-mime-security-button-end-line-format))
-      (gnus-insert-mime-security-button handle))
+    (unless (gnus-unbuttonized-mime-type-p (car handle))
+      (let ((gnus-mime-security-button-line-format
+            gnus-mime-security-button-end-line-format))
+       (gnus-insert-mime-security-button handle)))
     (mm-set-handle-multipart-parameter
      handle 'gnus-region
      (cons (set-marker (make-marker) (point-min))