*** empty log message ***
[gnus] / lisp / gnus-sum.el
index 7049e89..fd1039f 100644 (file)
@@ -1,7 +1,7 @@
 ;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996,97 Free Software Foundation, Inc.
+;; Copyright (C) 1996,97,98 Free Software Foundation, Inc.
 
-;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news
 
 ;; This file is part of GNU Emacs.
 
 ;;; Code:
 
+(eval-when-compile (require 'cl))
+
 (require 'gnus)
 (require 'gnus-group)
 (require 'gnus-spec)
 (require 'gnus-range)
 (require 'gnus-int)
 (require 'gnus-undo)
+(require 'gnus-util)
+(autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
 
 (defcustom gnus-kill-summary-on-exit t
   "*If non-nil, kill the summary buffer when you exit from it.
@@ -45,10 +49,11 @@ If an unread article in the group refers to an older, already read (or
 just marked as read) article, the old article will not normally be
 displayed in the Summary buffer.  If this variable is non-nil, Gnus
 will attempt to grab the headers to the old articles, and thereby
-build complete threads.         If it has the value `some', only enough
-headers to connect otherwise loose threads will be displayed.
-This variable can also be a number.  In that case, no more than that
-number of old headers will be fetched.
+build complete threads.  If it has the value `some', only enough
+headers to connect otherwise loose threads will be displayed.  This
+variable can also be a number.  In that case, no more than that number
+of old headers will be fetched.  If it has the value `invisible', all
+old headers will be fetched, but none will be displayed.
 
 The server has to support NOV for any of this to work."
   :group 'gnus-thread
@@ -57,6 +62,13 @@ The server has to support NOV for any of this to work."
                 number
                 (sexp :menu-tag "other" t)))
 
+(defcustom gnus-refer-thread-limit 200
+  "*The number of old headers to fetch when doing \\<gnus-summary-mode-map>\\[gnus-summary-refer-thread].
+If t, fetch all the available old headers."
+  :group 'gnus-thread
+  :type '(choice number
+                (sexp :menu-tag "other" t)))
+
 (defcustom gnus-summary-make-false-root 'adopt
   "*nil means that Gnus won't gather loose threads.
 If the root of a thread has expired or been read in a previous
@@ -109,6 +121,15 @@ comparing subjects."
                 (const fuzzy)
                 (sexp :menu-tag "on" t)))
 
+(defcustom gnus-simplify-subject-functions nil
+  "List of functions taking a string argument that simplify subjects.
+The functions are applied recursively.
+
+Useful functions to put in this list include: `gnus-simplify-subject-re',
+`gnus-simplify-subject-fuzzy' and `gnus-simplify-whitespace'."
+  :group 'gnus-thread
+  :type '(repeat function))
+
 (defcustom gnus-simplify-ignored-prefixes nil
   "*Regexp, matches for which are removed from subject lines when simplifying fuzzily."
   :group 'gnus-thread
@@ -128,17 +149,16 @@ non-nil and non-`some', fill in all gaps that Gnus manages to guess."
 
 (defcustom gnus-summary-thread-gathering-function
   'gnus-gather-threads-by-subject
-  "Function used for gathering loose threads.
+  "*Function used for gathering loose threads.
 There are two pre-defined functions: `gnus-gather-threads-by-subject',
 which only takes Subjects into consideration; and
 `gnus-gather-threads-by-references', which compared the References
 headers of the articles to find matches."
   :group 'gnus-thread
-  :type '(set (function-item gnus-gather-threads-by-subject)
-             (function-item gnus-gather-threads-by-references)
-             (function :tag "other")))
+  :type '(radio (function-item gnus-gather-threads-by-subject)
+               (function-item gnus-gather-threads-by-references)
+               (function :tag "other")))
 
-;; Added by Per Abrahamsen <amanda@iesd.auc.dk>.
 (defcustom gnus-summary-same-subject ""
   "*String indicating that the current article has the same subject as the previous.
 This variable will only be used if the value of
@@ -317,9 +337,9 @@ The articles will simply be fed to the function given by
   "*Variable used to suggest where articles are to be moved to.
 It uses the same syntax as the `gnus-split-methods' variable."
   :group 'gnus-summary-mail
-  :type '(repeat (choice (list function)
-                        (cons regexp (repeat string))
-                        sexp)))
+  :type '(repeat (choice (list :value (fun) function)
+                        (cons :value ("" "") regexp (repeat string))
+                        (sexp :value nil))))
 
 (defcustom gnus-unread-mark ? 
   "*Mark used for unread articles."
@@ -411,6 +431,21 @@ It uses the same syntax as the `gnus-split-methods' variable."
   :group 'gnus-summary-marks
   :type 'character)
 
+(defcustom gnus-undownloaded-mark ?@
+  "*Mark used for articles that weren't downloaded."
+  :group 'gnus-summary-marks
+  :type 'character)
+
+(defcustom gnus-downloadable-mark ?%
+  "*Mark used for articles that are to be downloaded."
+  :group 'gnus-summary-marks
+  :type 'character)
+
+(defcustom gnus-unsendable-mark ?=
+  "*Mark used for articles that won't be sent."
+  :group 'gnus-summary-marks
+  :type 'character)
+
 (defcustom gnus-score-over-mark ?+
   "*Score mark used for articles with high scores."
   :group 'gnus-summary-marks
@@ -458,7 +493,7 @@ list of parameters to that command."
   :type 'boolean)
 
 (defcustom gnus-summary-dummy-line-format
-  "*  %(:                          :%) %S\n"
+  "  %(:                          :%) %S\n"
   "*The format specification for the dummy roots in the summary buffer.
 It works along the same lines as a normal formatting string,
 with some simple extensions.
@@ -475,6 +510,7 @@ with some simple extensions:
 %G  Group name
 %p  Unprefixed group name
 %A  Current article number
+%z  Current article score
 %V  Gnus version
 %U  Number of unread articles in the group
 %e  Number of unselected articles in the group
@@ -541,7 +577,8 @@ Some functions you can use are `+', `max', or `min'."
   :type 'function)
 
 (defcustom gnus-summary-expunge-below nil
-  "All articles that have a score less than this variable will be expunged."
+  "All articles that have a score less than this variable will be expunged.
+This variable is local to the summary buffers."
   :group 'gnus-score-default
   :type '(choice (const :tag "off" nil)
                 integer))
@@ -549,7 +586,9 @@ Some functions you can use are `+', `max', or `min'."
 (defcustom gnus-thread-expunge-below nil
   "All threads that have a total score less than this variable will be expunged.
 See `gnus-thread-score-function' for en explanation of what a
-\"thread score\" is."
+\"thread score\" is.
+
+This variable is local to the summary buffers."
   :group 'gnus-treading
   :group 'gnus-score-default
   :type '(choice (const :tag "off" nil)
@@ -578,6 +617,11 @@ If you want to modify the summary buffer, you can use this hook."
   :group 'gnus-summary-various
   :type 'hook)
 
+(defcustom gnus-summary-prepared-hook nil
+  "*A hook called as the last thing after the summary buffer has been generated."
+  :group 'gnus-summary-various
+  :type 'hook)
+
 (defcustom gnus-summary-generate-hook nil
   "*A hook run just before generating the summary buffer.
 This hook is commonly used to customize threading variables and the
@@ -617,6 +661,16 @@ is not run if `gnus-visual' is nil."
   :group 'gnus-summary-visual
   :type 'hook)
 
+(defcustom gnus-structured-field-decoder 'identity
+  "Function to decode non-ASCII characters in structured field for summary."
+  :group 'gnus-various
+  :type 'function)
+
+(defcustom gnus-unstructured-field-decoder 'identity
+  "Function to decode non-ASCII characters in unstructured field for summary."
+  :group 'gnus-various
+  :type 'function)
+
 (defcustom gnus-parse-headers-hook
   (list 'gnus-hack-decode-rfc1522 'gnus-decode-rfc1522)
   "*A hook called before parsing the headers."
@@ -685,7 +739,15 @@ automatically when it is selected."
      . gnus-summary-high-unread-face)
     ((and (< score default) (= mark gnus-unread-mark))
      . gnus-summary-low-unread-face)
-    ((and (= mark gnus-unread-mark))
+    ((= mark gnus-unread-mark)
+     . gnus-summary-normal-unread-face)
+    ((and (> score default) (memq mark (list gnus-downloadable-mark
+                                            gnus-undownloaded-mark)))
+     . gnus-summary-high-unread-face)
+    ((and (< score default) (memq mark (list gnus-downloadable-mark
+                                            gnus-undownloaded-mark)))
+     . gnus-summary-low-unread-face)
+    ((memq mark (list gnus-downloadable-mark gnus-undownloaded-mark))
      . gnus-summary-normal-unread-face)
     ((> score default)
      . gnus-summary-high-read-face)
@@ -693,7 +755,7 @@ automatically when it is selected."
      . gnus-summary-low-read-face)
     (t
      . gnus-summary-normal-read-face))
-  "Controls the highlighting of summary buffer lines.
+  "*Controls the highlighting of summary buffer lines.
 
 A list of (FORM . FACE) pairs.  When deciding how a a particular
 summary line should be displayed, each form is evaluated.  The content
@@ -710,6 +772,10 @@ mark:    The articles mark."
   :type '(repeat (cons (sexp :tag "Form" nil)
                       face)))
 
+(defcustom gnus-alter-header-function nil
+  "Function called to allow alteration of article header structures.
+The function is called with one parameter, the article header vector,
+which it may alter in any way.")
 
 ;;; Internal variables
 
@@ -752,7 +818,7 @@ mark:    The articles mark."
     (?x ,(macroexpand '(mail-header-xref gnus-tmp-header)) ?s)
     (?D ,(macroexpand '(mail-header-date gnus-tmp-header)) ?s)
     (?d (gnus-dd-mmm (mail-header-date gnus-tmp-header)) ?s)
-    (?o (gnus-date-iso8601 gnus-tmp-header) ?s)
+    (?o (gnus-date-iso8601 (mail-header-date gnus-tmp-header)) ?s)
     (?M ,(macroexpand '(mail-header-id gnus-tmp-header)) ?s)
     (?r ,(macroexpand '(mail-header-references gnus-tmp-header)) ?s)
     (?c (or (mail-header-chars gnus-tmp-header) 0) ?d)
@@ -800,6 +866,7 @@ variable (string, integer, character, etc).")
     (?d (length gnus-newsgroup-dormant) ?d)
     (?t (length gnus-newsgroup-marked) ?d)
     (?r (length gnus-newsgroup-reads) ?d)
+    (?z (gnus-summary-article-score gnus-tmp-article-number) ?d)
     (?E gnus-newsgroup-expunged-tally ?d)
     (?s (gnus-current-score-file-nondirectory) ?s)))
 
@@ -857,6 +924,15 @@ variable (string, integer, character, etc).")
 (defvar gnus-newsgroup-processable nil
   "List of articles in the current newsgroup that can be processed.")
 
+(defvar gnus-newsgroup-downloadable nil
+  "List of articles in the current newsgroup that can be processed.")
+
+(defvar gnus-newsgroup-undownloaded nil
+  "List of articles in the current newsgroup that haven't been downloaded..")
+
+(defvar gnus-newsgroup-unsendable nil
+  "List of articles in the current newsgroup that won't be sent.")
+
 (defvar gnus-newsgroup-bookmarks nil
   "List of articles in the current newsgroup that have bookmarks.")
 
@@ -896,6 +972,8 @@ variable (string, integer, character, etc).")
     gnus-newsgroup-reads gnus-newsgroup-saved
     gnus-newsgroup-replied gnus-newsgroup-expirable
     gnus-newsgroup-processable gnus-newsgroup-killed
+    gnus-newsgroup-downloadable gnus-newsgroup-undownloaded
+    gnus-newsgroup-unsendable
     gnus-newsgroup-bookmarks gnus-newsgroup-dormant
     gnus-newsgroup-headers gnus-newsgroup-threads
     gnus-newsgroup-prepared gnus-summary-highlight-line-function
@@ -922,6 +1000,22 @@ variable (string, integer, character, etc).")
 
 ;; Subject simplification.
 
+(defun gnus-simplify-whitespace (str)
+  "Remove excessive whitespace."
+  (let ((mystr str))
+    ;; Multiple spaces.
+    (while (string-match "[ \t][ \t]+" mystr)
+      (setq mystr (concat (substring mystr 0 (match-beginning 0))
+                          " "
+                          (substring mystr (match-end 0)))))
+    ;; Leading spaces.
+    (when (string-match "^[ \t]+" mystr)
+      (setq mystr (substring mystr (match-end 0))))
+    ;; Trailing spaces.
+    (when (string-match "[ \t]+$" mystr)
+      (setq mystr (substring mystr 0 (match-beginning 0))))
+    mystr))
+
 (defsubst gnus-simplify-subject-re (subject)
   "Remove \"Re:\" from subject lines."
   (if (string-match "^[Rr][Ee]: *" subject)
@@ -985,10 +1079,14 @@ gnus-simplify-subject-fuzzy-regexp."
 
 (defun gnus-simplify-subject-fuzzy (subject)
   "Simplify a subject string fuzzily.
-See gnus-simplify-buffer-fuzzy for details."
+See `gnus-simplify-buffer-fuzzy' for details."
   (save-excursion
     (gnus-set-work-buffer)
     (let ((case-fold-search t))
+      ;; Remove uninteresting prefixes.
+      (when (and gnus-simplify-ignored-prefixes
+                (string-match gnus-simplify-ignored-prefixes subject))
+       (setq subject (substring subject (match-end 0))))
       (insert subject)
       (inline (gnus-simplify-buffer-fuzzy))
       (buffer-string))))
@@ -996,6 +1094,8 @@ See gnus-simplify-buffer-fuzzy for details."
 (defsubst gnus-simplify-subject-fully (subject)
   "Simplify a subject string according to gnus-summary-gather-subject-limit."
   (cond
+   (gnus-simplify-subject-functions
+    (gnus-map-function gnus-simplify-subject-functions subject))
    ((null gnus-summary-gather-subject-limit)
     (gnus-simplify-subject-re subject))
    ((eq gnus-summary-gather-subject-limit 'fuzzy)
@@ -1007,8 +1107,9 @@ See gnus-simplify-buffer-fuzzy for details."
     subject)))
 
 (defsubst gnus-subject-equal (s1 s2 &optional simple-first)
-  "Check whether two subjects are equal.  If optional argument
-simple-first is t, first argument is already simplified."
+  "Check whether two subjects are equal.
+If optional argument simple-first is t, first argument is already
+simplified."
   (cond
    ((null simple-first)
     (equal (gnus-simplify-subject-fully s1)
@@ -1037,6 +1138,7 @@ increase the score of each group you read."
     " " gnus-summary-next-page
     "\177" gnus-summary-prev-page
     [delete] gnus-summary-prev-page
+    [backspace] gnus-summary-prev-page
     "\r" gnus-summary-scroll-up
     "n" gnus-summary-next-unread-article
     "p" gnus-summary-prev-unread-article
@@ -1122,6 +1224,7 @@ increase the score of each group you read."
     "\C-c\C-v\C-v" gnus-uu-decode-uu-view
     "\C-d" gnus-summary-enter-digest-group
     "\M-\C-d" gnus-summary-read-document
+    "\M-\C-e" gnus-summary-edit-parameters
     "\C-c\C-b" gnus-bug
     "*" gnus-cache-enter-article
     "\M-*" gnus-cache-remove-article
@@ -1129,7 +1232,9 @@ increase the score of each group you read."
     "\C-l" gnus-recenter
     "I" gnus-summary-increase-score
     "L" gnus-summary-lower-score
-
+    "\M-i" gnus-symbolic-argument
+    "h" gnus-summary-select-article-buffer
+    
     "V" gnus-summary-score-map
     "X" gnus-uu-extract-map
     "S" gnus-summary-send-map)
@@ -1172,7 +1277,9 @@ increase the score of each group you read."
     "u" gnus-summary-limit-to-unread
     "m" gnus-summary-limit-to-marks
     "v" gnus-summary-limit-to-score
+    "*" gnus-summary-limit-include-cached
     "D" gnus-summary-limit-include-dormant
+    "T" gnus-summary-limit-include-thread
     "d" gnus-summary-limit-exclude-dormant
     "t" gnus-summary-limit-to-age
     "E" gnus-summary-limit-include-expunged
@@ -1245,6 +1352,7 @@ increase the score of each group you read."
     "^" gnus-summary-refer-parent-article
     "r" gnus-summary-refer-parent-article
     "R" gnus-summary-refer-references
+    "T" gnus-summary-refer-thread
     "g" gnus-summary-show-article
     "s" gnus-summary-isearch-article
     "P" gnus-summary-print-article)
@@ -1263,7 +1371,8 @@ increase the score of each group you read."
     "t" gnus-article-hide-headers
     "v" gnus-summary-verbose-headers
     "m" gnus-summary-toggle-mime
-    "h" gnus-article-treat-html)
+    "h" gnus-article-treat-html
+    "d" gnus-article-treat-dumbquotes)
 
   (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
     "a" gnus-article-hide
@@ -1287,6 +1396,7 @@ increase the score of each group you read."
     "l" gnus-article-date-local
     "e" gnus-article-date-lapsed
     "o" gnus-article-date-original
+    "i" gnus-article-date-iso8601
     "s" gnus-article-date-user)
 
   (gnus-define-keys (gnus-summary-wash-empty-map "E" gnus-summary-wash-map)
@@ -1294,6 +1404,7 @@ increase the score of each group you read."
     "l" gnus-article-strip-leading-blank-lines
     "m" gnus-article-strip-multiple-blank-lines
     "a" gnus-article-strip-blank-lines
+    "A" gnus-article-strip-all-blank-lines
     "s" gnus-article-strip-leading-space)
 
   (gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
@@ -1314,6 +1425,7 @@ increase the score of each group you read."
     "c" gnus-summary-copy-article
     "B" gnus-summary-crosspost-article
     "q" gnus-summary-respool-query
+    "t" gnus-summary-respool-trace
     "i" gnus-summary-import-article
     "p" gnus-summary-article-posted-p)
 
@@ -1362,208 +1474,112 @@ increase the score of each group you read."
         ["Increase score..." gnus-summary-increase-score t]
         ["Lower score..." gnus-summary-lower-score t]))))
 
-    '(("Default header"
-       ["Ask" (gnus-score-set-default 'gnus-score-default-header nil)
-       :style radio
-       :selected (null gnus-score-default-header)]
-       ["From" (gnus-score-set-default 'gnus-score-default-header 'a)
-       :style radio
-       :selected (eq gnus-score-default-header 'a)]
-       ["Subject" (gnus-score-set-default 'gnus-score-default-header 's)
-       :style radio
-       :selected (eq gnus-score-default-header 's)]
-       ["Article body"
-       (gnus-score-set-default 'gnus-score-default-header 'b)
-       :style radio
-       :selected (eq gnus-score-default-header 'b )]
-       ["All headers"
-       (gnus-score-set-default 'gnus-score-default-header 'h)
-       :style radio
-       :selected (eq gnus-score-default-header 'h )]
-       ["Message-ID" (gnus-score-set-default 'gnus-score-default-header 'i)
-       :style radio
-       :selected (eq gnus-score-default-header 'i )]
-       ["Thread" (gnus-score-set-default 'gnus-score-default-header 't)
-       :style radio
-       :selected (eq gnus-score-default-header 't )]
-       ["Crossposting"
-       (gnus-score-set-default 'gnus-score-default-header 'x)
-       :style radio
-       :selected (eq gnus-score-default-header 'x )]
-       ["Lines" (gnus-score-set-default 'gnus-score-default-header 'l)
-       :style radio
-       :selected (eq gnus-score-default-header 'l )]
-       ["Date" (gnus-score-set-default 'gnus-score-default-header 'd)
-       :style radio
-       :selected (eq gnus-score-default-header 'd )]
-       ["Followups to author"
-       (gnus-score-set-default 'gnus-score-default-header 'f)
-       :style radio
-       :selected (eq gnus-score-default-header 'f )])
-      ("Default type"
-       ["Ask" (gnus-score-set-default 'gnus-score-default-type nil)
-       :style radio
-       :selected (null gnus-score-default-type)]
-       ;; The `:active' key is commented out in the following,
-       ;; because the GNU Emacs hack to support radio buttons use
-       ;; active to indicate which button is selected.
-       ["Substring" (gnus-score-set-default 'gnus-score-default-type 's)
-       :style radio
-       ;; :active (not (memq gnus-score-default-header '(l d)))
-       :selected (eq gnus-score-default-type 's)]
-       ["Regexp" (gnus-score-set-default 'gnus-score-default-type 'r)
-       :style radio
-       ;; :active (not (memq gnus-score-default-header '(l d)))
-       :selected (eq gnus-score-default-type 'r)]
-       ["Exact" (gnus-score-set-default 'gnus-score-default-type 'e)
-       :style radio
-       ;; :active (not (memq gnus-score-default-header '(l d)))
-       :selected (eq gnus-score-default-type 'e)]
-       ["Fuzzy" (gnus-score-set-default 'gnus-score-default-type 'f)
-       :style radio
-       ;; :active (not (memq gnus-score-default-header '(l d)))
-       :selected (eq gnus-score-default-type 'f)]
-       ["Before date" (gnus-score-set-default 'gnus-score-default-type 'b)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'd))
-       :selected (eq gnus-score-default-type 'b)]
-       ["At date" (gnus-score-set-default 'gnus-score-default-type 'n)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'd))
-       :selected (eq gnus-score-default-type 'n)]
-       ["After date" (gnus-score-set-default 'gnus-score-default-type 'a)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'd))
-       :selected (eq gnus-score-default-type 'a)]
-       ["Less than number"
-       (gnus-score-set-default 'gnus-score-default-type '<)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'l))
-       :selected (eq gnus-score-default-type '<)]
-       ["Equal to number"
-       (gnus-score-set-default 'gnus-score-default-type '=)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'l))
-       :selected (eq gnus-score-default-type '=)]
-       ["Greater than number"
-       (gnus-score-set-default 'gnus-score-default-type '>)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'l))
-       :selected (eq gnus-score-default-type '>)])
-      ["Default fold" gnus-score-default-fold-toggle
-       :style toggle
-       :selected gnus-score-default-fold]
-      ("Default duration"
-       ["Ask" (gnus-score-set-default 'gnus-score-default-duration nil)
-       :style radio
-       :selected (null gnus-score-default-duration)]
-       ["Permanent"
-       (gnus-score-set-default 'gnus-score-default-duration 'p)
-       :style radio
-       :selected (eq gnus-score-default-duration 'p)]
-       ["Temporary"
-       (gnus-score-set-default 'gnus-score-default-duration 't)
-       :style radio
-       :selected (eq gnus-score-default-duration 't)]
-       ["Immediate"
-       (gnus-score-set-default 'gnus-score-default-duration 'i)
-       :style radio
-       :selected (eq gnus-score-default-duration 'i)]))
-
-    (easy-menu-define
-     gnus-summary-article-menu gnus-summary-mode-map ""
-     '("Article"
-       ("Hide"
-       ["All" gnus-article-hide t]
-       ["Headers" gnus-article-hide-headers t]
-       ["Signature" gnus-article-hide-signature t]
-       ["Citation" gnus-article-hide-citation t]
-       ["PGP" gnus-article-hide-pgp t]
-       ["Boring headers" gnus-article-hide-boring-headers t])
-       ("Highlight"
-       ["All" gnus-article-highlight t]
-       ["Headers" gnus-article-highlight-headers t]
-       ["Signature" gnus-article-highlight-signature t]
-       ["Citation" gnus-article-highlight-citation t])
-       ("Date"
-       ["Local" gnus-article-date-local t]
-       ["UT" gnus-article-date-ut t]
-       ["Original" gnus-article-date-original t]
-       ["Lapsed" gnus-article-date-lapsed t]
-       ["User-defined" gnus-article-date-user t])
-       ("Washing"
-       ("Remove Blanks"
-        ["Leading" gnus-article-strip-leading-blank-lines t]
-        ["Multiple" gnus-article-strip-multiple-blank-lines t]
-        ["Trailing" gnus-article-remove-trailing-blank-lines t]
-        ["All of the above" gnus-article-strip-blank-lines t]
-        ["Leading space" gnus-article-strip-leading-space t])
-       ["Overstrike" gnus-article-treat-overstrike t]
-       ["Emphasis" gnus-article-emphasize t]
-       ["Word wrap" gnus-article-fill-cited-article t]
-       ["CR" gnus-article-remove-cr t]
-       ["Show X-Face" gnus-article-display-x-face t]
-       ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
-       ["UnHTMLize" gnus-article-treat-html t]
-       ["Rot 13" gnus-summary-caesar-message t]
-       ["Unix pipe" gnus-summary-pipe-message t]
-       ["Add buttons" gnus-article-add-buttons t]
-       ["Add buttons to head" gnus-article-add-buttons-to-head t]
-       ["Stop page breaking" gnus-summary-stop-page-breaking t]
-       ["Toggle MIME" gnus-summary-toggle-mime t]
-       ["Verbose header" gnus-summary-verbose-headers t]
-       ["Toggle header" gnus-summary-toggle-header t])
-       ("Output"
-       ["Save in default format" gnus-summary-save-article t]
-       ["Save in file" gnus-summary-save-article-file t]
-       ["Save in Unix mail format" gnus-summary-save-article-mail t]
-       ["Write to file" gnus-summary-write-article-mail t]
-       ["Save in MH folder" gnus-summary-save-article-folder t]
-       ["Save in VM folder" gnus-summary-save-article-vm t]
-       ["Save in RMAIL mbox" gnus-summary-save-article-rmail t]
-       ["Save body in file" gnus-summary-save-article-body-file t]