1 ;;; gnus-art.el --- article mode commands for Gnus
3 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 ;; 2005, 2006 Free Software Foundation, Inc.
6 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
33 (defvar w3m-minor-mode-map))
36 ;; Avoid the "Recursive load suspected" error in Emacs 21.1.
38 (let ((recursive-load-depth-limit 100))
51 (autoload 'gnus-msg-mail "gnus-msg" nil t)
52 (autoload 'gnus-button-mailto "gnus-msg")
53 (autoload 'gnus-button-reply "gnus-msg" nil t)
54 (autoload 'parse-time-string "parse-time" nil nil)
55 (autoload 'ansi-color-apply-on-region "ansi-color")
57 (defgroup gnus-article nil
59 :link '(custom-manual "(gnus)Article Buffer")
62 (defgroup gnus-article-treat nil
63 "Treating article parts."
64 :link '(custom-manual "(gnus)Article Hiding")
67 (defgroup gnus-article-hiding nil
68 "Hiding article parts."
69 :link '(custom-manual "(gnus)Article Hiding")
72 (defgroup gnus-article-highlight nil
73 "Article highlighting."
74 :link '(custom-manual "(gnus)Article Highlighting")
78 (defgroup gnus-article-signature nil
80 :link '(custom-manual "(gnus)Article Signature")
83 (defgroup gnus-article-headers nil
85 :link '(custom-manual "(gnus)Hiding Headers")
88 (defgroup gnus-article-washing nil
89 "Special commands on articles."
90 :link '(custom-manual "(gnus)Article Washing")
93 (defgroup gnus-article-emphasis nil
94 "Fontisizing articles."
95 :link '(custom-manual "(gnus)Article Fontisizing")
98 (defgroup gnus-article-saving nil
100 :link '(custom-manual "(gnus)Saving Articles")
101 :group 'gnus-article)
103 (defgroup gnus-article-mime nil
104 "Worshiping the MIME wonder."
105 :link '(custom-manual "(gnus)Using MIME")
106 :group 'gnus-article)
108 (defgroup gnus-article-buttons nil
109 "Pushable buttons in the article buffer."
110 :link '(custom-manual "(gnus)Article Buttons")
111 :group 'gnus-article)
113 (defgroup gnus-article-various nil
114 "Other article options."
115 :link '(custom-manual "(gnus)Misc Article")
116 :group 'gnus-article)
118 (defcustom gnus-ignored-headers
121 (concat "^" header ":"))
122 '("Path" "Expires" "Date-Received" "References" "Xref" "Lines"
123 "Relay-Version" "Message-ID" "Approved" "Sender" "Received"
124 "X-UIDL" "MIME-Version" "Return-Path" "In-Reply-To"
125 "Content-Type" "Content-Transfer-Encoding" "X-WebTV-Signature"
126 "X-MimeOLE" "X-MSMail-Priority" "X-Priority" "X-Loop"
127 "X-Authentication-Warning" "X-MIME-Autoconverted" "X-Face"
128 "X-Attribution" "X-Originating-IP" "Delivered-To"
129 "NNTP-[-A-Za-z]+" "Distribution" "X-no-archive" "X-Trace"
130 "X-Complaints-To" "X-NNTP-Posting-Host" "X-Orig.*"
131 "Abuse-Reports-To" "Cache-Post-Path" "X-Article-Creation-Date"
132 "X-Poster" "X-Mail2News-Path" "X-Server-Date" "X-Cache"
133 "Originator" "X-Problems-To" "X-Auth-User" "X-Post-Time"
134 "X-Admin" "X-UID" "Resent-[-A-Za-z]+" "X-Mailing-List"
135 "Precedence" "Original-[-A-Za-z]+" "X-filename" "X-Orcpt"
136 "Old-Received" "X-Pgp" "X-Auth" "X-From-Line"
137 "X-Gnus-Article-Number" "X-Majordomo" "X-Url" "X-Sender"
138 "MBOX-Line" "Priority" "X400-[-A-Za-z]+"
139 "Status" "X-Gnus-Mail-Source" "Cancel-Lock"
140 "X-FTN" "X-EXP32-SerialNo" "Encoding" "Importance"
141 "Autoforwarded" "Original-Encoded-Information-Types" "X-Ya-Pop3"
142 "X-Face-Version" "X-Vms-To" "X-ML-NAME" "X-ML-COUNT"
143 "Mailing-List" "X-finfo" "X-md5sum" "X-md5sum-Origin"
144 "X-Sun-Charset" "X-Accept-Language" "X-Envelope-Sender"
145 "List-[A-Za-z]+" "X-Listprocessor-Version"
146 "X-Received" "X-Distribute" "X-Sequence" "X-Juno-Line-Breaks"
147 "X-Notes-Item" "X-MS-TNEF-Correlator" "x-uunet-gateway"
148 "X-Received" "Content-length" "X-precedence"
149 "X-Authenticated-User" "X-Comment" "X-Report" "X-Abuse-Info"
150 "X-HTTP-Proxy" "X-Mydeja-Info" "X-Copyright" "X-No-Markup"
151 "X-Abuse-Info" "X-From_" "X-Accept-Language" "Errors-To"
152 "X-BeenThere" "X-Mailman-Version" "List-Help" "List-Post"
153 "List-Subscribe" "List-Id" "List-Unsubscribe" "List-Archive"
154 "X-Content-length" "X-Posting-Agent" "Original-Received"
155 "X-Request-PGP" "X-Fingerprint" "X-WRIEnvto" "X-WRIEnvfrom"
156 "X-Virus-Scanned" "X-Delivery-Agent" "Posted-Date" "X-Gateway"
157 "X-Local-Origin" "X-Local-Destination" "X-UserInfo1"
158 "X-Received-Date" "X-Hashcash" "Face" "X-DMCA-Notifications"
159 "X-Abuse-and-DMCA-Info" "X-Postfilter" "X-Gpg-.*" "X-Disclaimer"))
160 "*All headers that start with this regexp will be hidden.
161 This variable can also be a list of regexps of headers to be ignored.
162 If `gnus-visible-headers' is non-nil, this variable will be ignored."
163 :type '(choice :custom-show nil
166 :group 'gnus-article-hiding)
168 (defcustom gnus-visible-headers
169 "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^[BGF]?Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Mail-Followup-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-From:\\|^X-Sent:"
170 "*All headers that do not match this regexp will be hidden.
171 This variable can also be a list of regexp of headers to remain visible.
172 If this variable is non-nil, `gnus-ignored-headers' will be ignored."
173 :type '(repeat :value-to-internal (lambda (widget value)
174 (custom-split-regexp-maybe value))
175 :match (lambda (widget value)
177 (widget-editable-list-match widget value)))
179 :group 'gnus-article-hiding)
181 (defcustom gnus-sorted-header-list
182 '("^From:" "^Subject:" "^Summary:" "^Keywords:" "^Newsgroups:"
183 "^Followup-To:" "^To:" "^Cc:" "^Date:" "^Organization:")
184 "*This variable is a list of regular expressions.
185 If it is non-nil, headers that match the regular expressions will
186 be placed first in the article buffer in the sequence specified by
188 :type '(repeat regexp)
189 :group 'gnus-article-hiding)
191 (defcustom gnus-boring-article-headers '(empty followup-to reply-to)
192 "Headers that are only to be displayed if they have interesting data.
193 Possible values in this list are:
195 'empty Headers with no content.
196 'newsgroups Newsgroup identical to Gnus group.
197 'to-address To identical to To-address.
198 'to-list To identical to To-list.
199 'cc-list CC identical to To-list.
200 'followup-to Followup-to identical to Newsgroups.
201 'reply-to Reply-to identical to From.
202 'date Date less than four days old.
203 'long-to To and/or Cc longer than 1024 characters.
204 'many-to Multiple To and/or Cc."
205 :type '(set (const :tag "Headers with no content." empty)
206 (const :tag "Newsgroups identical to Gnus group." newsgroups)
207 (const :tag "To identical to To-address." to-address)
208 (const :tag "To identical to To-list." to-list)
209 (const :tag "CC identical to To-list." cc-list)
210 (const :tag "Followup-to identical to Newsgroups." followup-to)
211 (const :tag "Reply-to identical to From." reply-to)
212 (const :tag "Date less than four days old." date)
213 (const :tag "To and/or Cc longer than 1024 characters." long-to)
214 (const :tag "Multiple To and/or Cc headers." many-to))
215 :group 'gnus-article-hiding)
217 (defcustom gnus-article-skip-boring nil
218 "Skip over text that is not worth reading.
219 By default, if you set this t, then Gnus will display citations and
220 signatures, but will never scroll down to show you a page consisting
221 only of boring text. Boring text is controlled by
222 `gnus-article-boring-faces'."
225 :group 'gnus-article-hiding)
227 (defcustom gnus-signature-separator '("^-- $" "^-- *$")
228 "Regexp matching signature separator.
229 This can also be a list of regexps. In that case, it will be checked
230 from head to tail looking for a separator. Searches will be done from
231 the end of the buffer."
232 :type '(choice :format "%{%t%}: %[Value Menu%]\n%v"
234 (repeat :tag "List of regexp" regexp))
235 :group 'gnus-article-signature)
237 (defcustom gnus-signature-limit nil
238 "Provide a limit to what is considered a signature.
239 If it is a number, no signature may not be longer (in characters) than
240 that number. If it is a floating point number, no signature may be
241 longer (in lines) than that number. If it is a function, the function
242 will be called without any parameters, and if it returns nil, there is
243 no signature in the buffer. If it is a string, it will be used as a
244 regexp. If it matches, the text in question is not a signature.
246 This can also be a list of the above values."
247 :type '(choice (const nil)
250 (function :value fun)
251 (regexp :value ".*"))
252 :group 'gnus-article-signature)
254 (defcustom gnus-hidden-properties '(invisible t intangible t)
255 "Property list to use for hiding text."
257 :group 'gnus-article-hiding)
259 ;; Fixme: This isn't the right thing for mixed graphical and non-graphical
260 ;; frames in a session.
261 (defcustom gnus-article-x-face-command
262 (if (featurep 'xemacs)
263 (if (or (gnus-image-type-available-p 'xface)
264 (gnus-image-type-available-p 'pbm))
265 'gnus-display-x-face-in-from
266 "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | ee -")
267 (if (gnus-image-type-available-p 'pbm)
268 'gnus-display-x-face-in-from
269 "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | \
271 "*String or function to be executed to display an X-Face header.
272 If it is a string, the command will be executed in a sub-shell
273 asynchronously. The compressed face will be piped to this command."
274 :type `(choice string
275 (function-item gnus-display-x-face-in-from)
279 :group 'gnus-article-washing)
281 (defcustom gnus-article-x-face-too-ugly nil
282 "Regexp matching posters whose face shouldn't be shown automatically."
283 :type '(choice regexp (const nil))
284 :group 'gnus-article-washing)
286 (defcustom gnus-article-banner-alist nil
287 "Banner alist for stripping.
289 ((egroups . \"^[ \\t\\n]*-------------------+\\\\( \\\\(e\\\\|Yahoo! \\\\)Groups Sponsor -+\\\\)?....\\n\\\\(.+\\n\\\\)+\"))"
291 :type '(repeat (cons symbol regexp))
292 :group 'gnus-article-washing)
294 (gnus-define-group-parameter
297 "Alist of regexps (to match group names) and banner."
298 :variable-group gnus-article-washing
300 '(choice :tag "Banner"
302 (const :tag "Remove signature" signature)
303 (symbol :tag "Item in `gnus-article-banner-alist'" none)
305 (const :tag "None" nil))
307 "If non-nil, specify how to remove `banners' from articles.
309 Symbol `signature' means to remove signatures delimited by
310 `gnus-signature-separator'. Any other symbol is used to look up a
311 regular expression to match the banner in `gnus-article-banner-alist'.
312 A string is used as a regular expression to match the banner
315 (defcustom gnus-article-address-banner-alist nil
316 "Alist of mail addresses and banners.
317 Each element has the form (ADDRESS . BANNER), where ADDRESS is a regexp
318 to match a mail address in the From: header, BANNER is one of a symbol
319 `signature', an item in `gnus-article-banner-alist', a regexp and nil.
320 If ADDRESS matches author's mail address, it will remove things like
321 advertisements. For example:
323 \((\"@yoo-hoo\\\\.co\\\\.jp\\\\'\" . \"\\n_+\\nDo You Yoo-hoo!\\\\?\\n.*\\n.*\\n\"))
327 (regexp :tag "Address")
328 (choice :tag "Banner" :value nil
329 (const :tag "Remove signature" signature)
330 (symbol :tag "Item in `gnus-article-banner-alist'" none)
332 (const :tag "None" nil))))
334 :group 'gnus-article-washing)
336 (defmacro gnus-emphasis-custom-with-format (&rest body)
338 \\(\\s-\\|^\\|\\=\\|[-\"]\\|\\s(\\)\\(%s\\(\\w+\\(\\s-+\\w+\\)*[.,]?\\)%s\\)\
339 \\(\\([-,.;:!?\"]\\|\\s)\\)+\\s-\\|[?!.]\\s-\\|\\s)\\|\\s-\\)"))
342 (defun gnus-emphasis-custom-value-to-external (value)
343 (gnus-emphasis-custom-with-format
344 (if (consp (car value))
345 (list (format format (car (car value)) (cdr (car value)))
347 (if (nth 1 value) 2 3)
351 (defun gnus-emphasis-custom-value-to-internal (value)
352 (gnus-emphasis-custom-with-format
353 (let ((regexp (concat "\\`"
354 (format (regexp-quote format)
355 "\\([^()]+\\)" "\\([^()]+\\)")
358 (if (string-match regexp (setq pattern (car value)))
359 (list (cons (match-string 1 pattern) (match-string 2 pattern))
364 (defcustom gnus-emphasis-alist
366 '(("\\*" "\\*" bold nil 2)
369 ("_/" "/_" underline-italic)
370 ("_\\*" "\\*_" underline-bold)
371 ("\\*/" "/\\*" bold-italic)
372 ("_\\*/" "/\\*_" underline-bold-italic))))
374 (gnus-emphasis-custom-with-format
375 (mapcar (lambda (spec)
376 (list (format format (car spec) (cadr spec))
379 (intern (format "gnus-emphasis-%s" (nth 2 spec)))))
381 '(;; I've never seen anyone use this strikethru convention whereas I've
382 ;; several times seen it triggered by normal text. --Stef
383 ;; Miles suggests that this form is sometimes used but for italics,
384 ;; so maybe we should map it to `italic'.
385 ;; ("\\(\\s-\\|^\\)\\(-\\(\\(\\w\\|-[^-]\\)+\\)-\\)\\(\\s-\\|[?!.,;]\\)"
386 ;; 2 3 gnus-emphasis-strikethru)
387 ("\\(\\s-\\|^\\)\\(_\\(\\(\\w\\|_[^_]\\)+\\)_\\)\\(\\s-\\|[?!.,;]\\)"
388 2 3 gnus-emphasis-underline))))
389 "*Alist that says how to fontify certain phrases.
390 Each item looks like this:
392 (\"_\\\\(\\\\w+\\\\)_\" 0 1 'underline)
394 The first element is a regular expression to be matched. The second
395 is a number that says what regular expression grouping used to find
396 the entire emphasized word. The third is a number that says what
397 regexp grouping should be displayed and highlighted. The fourth
398 is the face used for highlighting."
402 :format "%[Customizing Style%]\n%v"
404 (group :tag "Default"
405 :value ("" 0 0 default)
408 (let ((value (widget-get
409 (cadr (widget-get (widget-get widget :parent)
412 (if (not (eq (nth 2 value) 'default))
416 (gnus-emphasis-custom-value-to-external value))))
417 (widget-group-value-create widget))
419 (integer :format "Match group: %v")
420 (integer :format "Emphasize group: %v")
423 :value (("_" . "_") nil default)
425 (regexp :format "Start regexp: %v")
426 (regexp :format "End regexp: %v"))
427 (boolean :format "Show start and end patterns: %[%v%]\n"
428 :on " On " :off " Off ")
430 :get (lambda (symbol)
431 (mapcar 'gnus-emphasis-custom-value-to-internal
432 (default-value symbol)))
433 :set (lambda (symbol value)
434 (set-default symbol (mapcar 'gnus-emphasis-custom-value-to-external
436 :group 'gnus-article-emphasis)
438 (defcustom gnus-emphasize-whitespace-regexp "^[ \t]+\\|[ \t]*\n"
439 "A regexp to describe whitespace which should not be emphasized.
440 Typical values are \"^[ \\t]+\\\\|[ \\t]*\\n\" and \"[ \\t]+\\\\|[ \\t]*\\n\".
441 The former avoids underlining of leading and trailing whitespace,
442 and the latter avoids underlining any whitespace at all."
444 :group 'gnus-article-emphasis
447 (defface gnus-emphasis-bold '((t (:bold t)))
448 "Face used for displaying strong emphasized text (*word*)."
449 :group 'gnus-article-emphasis)
451 (defface gnus-emphasis-italic '((t (:italic t)))
452 "Face used for displaying italic emphasized text (/word/)."
453 :group 'gnus-article-emphasis)
455 (defface gnus-emphasis-underline '((t (:underline t)))
456 "Face used for displaying underlined emphasized text (_word_)."
457 :group 'gnus-article-emphasis)
459 (defface gnus-emphasis-underline-bold '((t (:bold t :underline t)))
460 "Face used for displaying underlined bold emphasized text (_*word*_)."
461 :group 'gnus-article-emphasis)
463 (defface gnus-emphasis-underline-italic '((t (:italic t :underline t)))
464 "Face used for displaying underlined italic emphasized text (_/word/_)."
465 :group 'gnus-article-emphasis)
467 (defface gnus-emphasis-bold-italic '((t (:bold t :italic t)))
468 "Face used for displaying bold italic emphasized text (/*word*/)."
469 :group 'gnus-article-emphasis)
471 (defface gnus-emphasis-underline-bold-italic
472 '((t (:bold t :italic t :underline t)))
473 "Face used for displaying underlined bold italic emphasized text.
474 Example: (_/*word*/_)."
475 :group 'gnus-article-emphasis)
477 (defface gnus-emphasis-strikethru (if (featurep 'xemacs)
478 '((t (:strikethru t)))
479 '((t (:strike-through t))))
480 "Face used for displaying strike-through text (-word-)."
481 :group 'gnus-article-emphasis)
483 (defface gnus-emphasis-highlight-words
484 '((t (:background "black" :foreground "yellow")))
485 "Face used for displaying highlighted words."
486 :group 'gnus-article-emphasis)
488 (defcustom gnus-article-time-format "%a, %d %b %Y %T %Z"
489 "Format for display of Date headers in article bodies.
490 See `format-time-string' for the possible values.
492 The variable can also be function, which should return a complete Date
493 header. The function is called with one argument, the time, which can
494 be fed to `format-time-string'."
495 :type '(choice string function)
496 :link '(custom-manual "(gnus)Article Date")
497 :group 'gnus-article-washing)
499 (defcustom gnus-save-all-headers t
500 "*If non-nil, don't remove any headers before saving."
501 :group 'gnus-article-saving
504 (defcustom gnus-prompt-before-saving 'always
505 "*This variable says how much prompting is to be done when saving articles.
506 If it is nil, no prompting will be done, and the articles will be
507 saved to the default files. If this variable is `always', each and
508 every article that is saved will be preceded by a prompt, even when
509 saving large batches of articles. If this variable is neither nil not
510 `always', there the user will be prompted once for a file name for
511 each invocation of the saving commands."
512 :group 'gnus-article-saving
513 :type '(choice (item always)
514 (item :tag "never" nil)
515 (sexp :tag "once" :format "%t\n" :value t)))
517 (defcustom gnus-saved-headers gnus-visible-headers
518 "Headers to keep if `gnus-save-all-headers' is nil.
519 If `gnus-save-all-headers' is non-nil, this variable will be ignored.
520 If that variable is nil, however, all headers that match this regexp
521 will be kept while the rest will be deleted before saving."
522 :group 'gnus-article-saving
525 (defcustom gnus-default-article-saver 'gnus-summary-save-in-rmail
526 "A function to save articles in your favourite format.
527 The function must be interactively callable (in other words, it must
528 be an Emacs command).
530 Gnus provides the following functions:
532 * gnus-summary-save-in-rmail (Rmail format)
533 * gnus-summary-save-in-mail (Unix mail format)
534 * gnus-summary-save-in-folder (MH folder)
535 * gnus-summary-save-in-file (article format)
536 * gnus-summary-save-body-in-file (article body)
537 * gnus-summary-save-in-vm (use VM's folder format)
538 * gnus-summary-write-to-file (article format -- overwrite)."
539 :group 'gnus-article-saving
540 :type '(radio (function-item gnus-summary-save-in-rmail)
541 (function-item gnus-summary-save-in-mail)
542 (function-item gnus-summary-save-in-folder)
543 (function-item gnus-summary-save-in-file)
544 (function-item gnus-summary-save-body-in-file)
545 (function-item gnus-summary-save-in-vm)
546 (function-item gnus-summary-write-to-file)))
548 (defcustom gnus-rmail-save-name 'gnus-plain-save-name
549 "A function generating a file name to save articles in Rmail format.
550 The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE."
551 :group 'gnus-article-saving
554 (defcustom gnus-mail-save-name 'gnus-plain-save-name
555 "A function generating a file name to save articles in Unix mail format.
556 The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE."
557 :group 'gnus-article-saving
560 (defcustom gnus-folder-save-name 'gnus-folder-save-name
561 "A function generating a file name to save articles in MH folder.
562 The function is called with NEWSGROUP, HEADERS, and optional LAST-FOLDER."
563 :group 'gnus-article-saving
566 (defcustom gnus-file-save-name 'gnus-numeric-save-name
567 "A function generating a file name to save articles in article format.
568 The function is called with NEWSGROUP, HEADERS, and optional
570 :group 'gnus-article-saving
573 (defcustom gnus-split-methods
574 '((gnus-article-archive-name)
575 (gnus-article-nndoc-name))
576 "*Variable used to suggest where articles are to be saved.
577 For instance, if you would like to save articles related to Gnus in
578 the file \"gnus-stuff\", and articles related to VM in \"vm-stuff\",
579 you could set this variable to something like:
581 '((\"^Subject:.*gnus\\|^Newsgroups:.*gnus\" \"gnus-stuff\")
582 (\"^Subject:.*vm\\|^Xref:.*vm\" \"vm-stuff\"))
584 This variable is an alist where the key is the match and the
585 value is a list of possible files to save in if the match is
588 If the match is a string, it is used as a regexp match on the
589 article. If the match is a symbol, that symbol will be funcalled
590 from the buffer of the article to be saved with the newsgroup as
591 the parameter. If it is a list, it will be evaled in the same
594 If this form or function returns a string, this string will be
595 used as a possible file name; and if it returns a non-nil list,
596 that list will be used as possible file names."
597 :group 'gnus-article-saving
598 :type '(repeat (choice (list :value (fun) function)
599 (cons :value ("" "") regexp (repeat string))
602 (defcustom gnus-page-delimiter "^\^L"
603 "*Regexp describing what to use as article page delimiters.
604 The default value is \"^\^L\", which is a form linefeed at the
605 beginning of a line."
607 :group 'gnus-article-various)
609 (defcustom gnus-article-mode-line-format "Gnus: %g [%w] %S%m"
610 "*The format specification for the article mode line.
611 See `gnus-summary-mode-line-format' for a closer description.
613 The following additional specs are available:
615 %w The article washing status.
616 %m The number of MIME parts in the article."
618 :group 'gnus-article-various)
620 (defcustom gnus-article-mode-hook nil
621 "*A hook for Gnus article mode."
623 :group 'gnus-article-various)
625 (when (featurep 'xemacs)
626 ;; Extracted from gnus-xmas-define in order to preserve user settings
627 (when (fboundp 'turn-off-scroll-in-place)
628 (add-hook 'gnus-article-mode-hook 'turn-off-scroll-in-place))
629 ;; Extracted from gnus-xmas-redefine in order to preserve user settings
630 (add-hook 'gnus-article-mode-hook 'gnus-xmas-article-menu-add))
632 (defcustom gnus-article-menu-hook nil
633 "*Hook run after the creation of the article mode menu."
635 :group 'gnus-article-various)
637 (defcustom gnus-article-prepare-hook nil
638 "*A hook called after an article has been prepared in the article buffer."
640 :group 'gnus-article-various)
642 (defcustom gnus-copy-article-ignored-headers nil
643 "List of headers to be removed when copying an article.
644 Each element is a regular expression."
645 :version "23.0" ;; No Gnus
646 :type '(repeat regexp)
647 :group 'gnus-article-various)
649 (make-obsolete-variable 'gnus-article-hide-pgp-hook
650 "This variable is obsolete in Gnus 5.10.")
652 (defcustom gnus-article-button-face 'bold
653 "Face used for highlighting buttons in the article buffer.
655 An article button is a piece of text that you can activate by pressing
656 `RET' or `mouse-2' above it."
658 :group 'gnus-article-buttons)
660 (defcustom gnus-article-mouse-face 'highlight
661 "Face used for mouse highlighting in the article buffer.
663 Article buttons will be displayed in this face when the cursor is
666 :group 'gnus-article-buttons)
668 (defcustom gnus-signature-face 'gnus-signature
669 "Face used for highlighting a signature in the article buffer.
670 Obsolete; use the face `gnus-signature' for customizations instead."
672 :group 'gnus-article-highlight
673 :group 'gnus-article-signature)
675 (defface gnus-signature
678 "Face used for highlighting a signature in the article buffer."
679 :group 'gnus-article-highlight
680 :group 'gnus-article-signature)
681 ;; backward-compatibility alias
682 (put 'gnus-signature-face 'face-alias 'gnus-signature)
684 (defface gnus-header-from
687 (:foreground "spring green"))
690 (:foreground "red3"))
693 "Face used for displaying from headers."
694 :group 'gnus-article-headers
695 :group 'gnus-article-highlight)
696 ;; backward-compatibility alias
697 (put 'gnus-header-from-face 'face-alias 'gnus-header-from)
699 (defface gnus-header-subject
702 (:foreground "SeaGreen3"))
705 (:foreground "red4"))
707 (:bold t :italic t)))
708 "Face used for displaying subject headers."
709 :group 'gnus-article-headers
710 :group 'gnus-article-highlight)
711 ;; backward-compatibility alias
712 (put 'gnus-header-subject-face 'face-alias 'gnus-header-subject)
714 (defface gnus-header-newsgroups
717 (:foreground "yellow" :italic t))
720 (:foreground "MidnightBlue" :italic t))
723 "Face used for displaying newsgroups headers.
724 In the default setup this face is only used for crossposted
726 :group 'gnus-article-headers
727 :group 'gnus-article-highlight)
728 ;; backward-compatibility alias
729 (put 'gnus-header-newsgroups-face 'face-alias 'gnus-header-newsgroups)
731 (defface gnus-header-name
734 (:foreground "SeaGreen"))
737 (:foreground "maroon"))
740 "Face used for displaying header names."
741 :group 'gnus-article-headers
742 :group 'gnus-article-highlight)
743 ;; backward-compatibility alias
744 (put 'gnus-header-name-face 'face-alias 'gnus-header-name)
746 (defface gnus-header-content
749 (:foreground "forest green" :italic t))
752 (:foreground "indianred4" :italic t))
754 (:italic t))) "Face used for displaying header content."
755 :group 'gnus-article-headers
756 :group 'gnus-article-highlight)
757 ;; backward-compatibility alias
758 (put 'gnus-header-content-face 'face-alias 'gnus-header-content)
760 (defcustom gnus-header-face-alist
761 '(("From" nil gnus-header-from)
762 ("Subject" nil gnus-header-subject)
763 ("Newsgroups:.*," nil gnus-header-newsgroups)
764 ("" gnus-header-name gnus-header-content))
765 "*Controls highlighting of article headers.
767 An alist of the form (HEADER NAME CONTENT).
769 HEADER is a regular expression which should match the name of a
770 header and NAME and CONTENT are either face names or nil.
772 The name of each header field will be displayed using the face
773 specified by the first element in the list where HEADER matches
774 the header name and NAME is non-nil. Similarly, the content will
775 be displayed by the first non-nil matching CONTENT face."
776 :group 'gnus-article-headers
777 :group 'gnus-article-highlight
778 :type '(repeat (list (regexp :tag "Header")
780 (item :tag "skip" nil)
781 (face :value default))
782 (choice :tag "Content"
783 (item :tag "skip" nil)
784 (face :value default)))))
786 (defcustom gnus-article-decode-hook
787 '(article-decode-charset article-decode-encoded-words
788 article-decode-group-name article-decode-idna-rhs)
789 "*Hook run to decode charsets in articles."
790 :group 'gnus-article-headers
793 (defcustom gnus-display-mime-function 'gnus-display-mime
794 "Function to display MIME articles."
795 :group 'gnus-article-mime
798 (defvar gnus-decode-header-function 'mail-decode-encoded-word-region
799 "Function used to decode headers.")
801 (defvar gnus-article-dumbquotes-map
821 "Table for MS-to-Latin1 translation.")
823 (defcustom gnus-ignored-mime-types nil
824 "List of MIME types that should be ignored by Gnus."
826 :group 'gnus-article-mime
827 :type '(repeat regexp))
829 (defcustom gnus-unbuttonized-mime-types '(".*/.*")
830 "List of MIME types that should not be given buttons when rendered inline.
831 See also `gnus-buttonized-mime-types' which may override this variable.
832 This variable is only used when `gnus-inhibit-mime-unbuttonizing' is nil."
834 :group 'gnus-article-mime
835 :type '(repeat regexp))
837 (defcustom gnus-buttonized-mime-types nil
838 "List of MIME types that should be given buttons when rendered inline.
839 If set, this variable overrides `gnus-unbuttonized-mime-types'.
840 To see e.g. security buttons you could set this to
841 `(\"multipart/signed\")'. You could also add \"multipart/alternative\" to
842 this list to display radio buttons that allow you to choose one of two
843 media types those mails include. See also `mm-discouraged-alternatives'.
844 This variable is only used when `gnus-inhibit-mime-unbuttonizing' is nil."
846 :group 'gnus-article-mime
847 :type '(repeat regexp))
849 (defcustom gnus-inhibit-mime-unbuttonizing nil
850 "If non-nil, all MIME parts get buttons.
851 When nil (the default value), then some MIME parts do not get buttons,
852 as described by the variables `gnus-buttonized-mime-types' and
853 `gnus-unbuttonized-mime-types'."
855 :group 'gnus-article-mime
858 (defcustom gnus-body-boundary-delimiter "_"
859 "String used to delimit header and body.
860 This variable is used by `gnus-article-treat-body-boundary' which can
861 be controlled by `gnus-treat-body-boundary'."
863 :group 'gnus-article-various
864 :type '(choice (item :tag "None" :value nil)
867 (defcustom gnus-picon-databases '("/usr/lib/picon" "/usr/local/faces"
869 "Defines the location of the faces database.
870 For information on obtaining this database of pretty pictures, please
871 see http://www.cs.indiana.edu/picons/ftp/index.html"
873 :type '(repeat directory)
874 :link '(url-link :tag "download"
875 "http://www.cs.indiana.edu/picons/ftp/index.html")
876 :link '(custom-manual "(gnus)Picons")
879 (defun gnus-picons-installed-p ()
880 "Say whether picons are installed on your machine."
881 (let ((installed nil))
882 (dolist (database gnus-picon-databases)
883 (when (file-exists-p database)
887 (defcustom gnus-article-mime-part-function nil
888 "Function called with a MIME handle as the argument.
889 This is meant for people who want to do something automatic based
890 on parts -- for instance, adding Vcard info to a database."
891 :group 'gnus-article-mime
892 :type '(choice (const nil)
895 (defcustom gnus-mime-multipart-functions nil
896 "An alist of MIME types to functions to display them."
898 :group 'gnus-article-mime
899 :type '(repeat (cons :format "%v" (string :tag "MIME type") function)))
901 (defcustom gnus-article-date-lapsed-new-header nil
902 "Whether the X-Sent and Date headers can coexist.
903 When using `gnus-treat-date-lapsed', the \"X-Sent:\" header will
904 either replace the old \"Date:\" header (if this variable is nil), or
905 be added below it (otherwise)."
907 :group 'gnus-article-headers
910 (defcustom gnus-article-mime-match-handle-function 'undisplayed-alternative
911 "Function called with a MIME handle as the argument.
912 This is meant for people who want to view first matched part.
913 For `undisplayed-alternative' (default), the first undisplayed
914 part or alternative part is used. For `undisplayed', the first
915 undisplayed part is used. For a function, the first part which
916 the function return t is used. For nil, the first part is
919 :group 'gnus-article-mime
921 (item :tag "first" :value nil)
922 (item :tag "undisplayed" :value undisplayed)
923 (item :tag "undisplayed or alternative"
924 :value undisplayed-alternative)
927 (defcustom gnus-mime-action-alist
928 '(("save to file" . gnus-mime-save-part)
929 ("save and strip" . gnus-mime-save-part-and-strip)
930 ("replace with file" . gnus-mime-replace-part)
931 ("delete part" . gnus-mime-delete-part)
932 ("display as text" . gnus-mime-inline-part)
933 ("view the part" . gnus-mime-view-part)
934 ("pipe to command" . gnus-mime-pipe-part)
935 ("toggle display" . gnus-article-press-button)
936 ("toggle display" . gnus-article-view-part-as-charset)
937 ("view as type" . gnus-mime-view-part-as-type)
938 ("view internally" . gnus-mime-view-part-internally)
939 ("view externally" . gnus-mime-view-part-externally))
940 "An alist of actions that run on the MIME attachment."
941 :group 'gnus-article-mime
942 :type '(repeat (cons (string :tag "name")
945 (defcustom gnus-auto-select-part 1
946 "Advance to next MIME part when deleting or stripping parts.
948 When 0, point will be placed on the same part as before. When
949 positive (negative), move point forward (backwards) this many
950 parts. When nil, redisplay article."
951 :version "23.0" ;; No Gnus
952 :group 'gnus-article-mime
953 :type '(choice (const nil :tag "Redisplay article.")
954 (const 1 :tag "Next part.")
955 (const 0 :tag "Current part.")
959 ;;; The treatment variables
962 (defvar gnus-part-display-hook nil
963 "Hook called on parts that are to receive treatment.")
965 (defvar gnus-article-treat-custom
966 '(choice (const :tag "Off" nil)
968 (const :tag "Header" head)
969 (const :tag "First" first)
970 (const :tag "Last" last)
971 (integer :tag "Less")
972 (repeat :tag "Groups" regexp)
973 (sexp :tag "Predicate")))
975 (defvar gnus-article-treat-head-custom
976 '(choice (const :tag "Off" nil)
977 (const :tag "Header" head)))
979 (defvar gnus-article-treat-types '("text/plain")
982 (defvar gnus-inhibit-treatment nil
983 "Whether to inhibit treatment.")
985 (defcustom gnus-treat-highlight-signature '(or t (typep "text/x-vcard"))
986 "Highlight the signature.
987 Valid values are nil, t, `head', `first', `last', an integer or a
988 predicate. See Info node `(gnus)Customizing Articles'."
989 :group 'gnus-article-treat
990 :link '(custom-manual "(gnus)Customizing Articles")
991 :type gnus-article-treat-custom)
992 (put 'gnus-treat-highlight-signature 'highlight t)
994 (defcustom gnus-treat-buttonize 100000
996 Valid values are nil, t, `head', `first', `last', an integer or a
997 predicate. See Info node `(gnus)Customizing Articles'."
998 :group 'gnus-article-treat
999 :link '(custom-manual "(gnus)Customizing Articles")
1000 :type gnus-article-treat-custom)
1001 (put 'gnus-treat-buttonize 'highlight t)
1003 (defcustom gnus-treat-buttonize-head 'head
1004 "Add buttons to the head.
1005 Valid values are nil, t, `head', `first', `last', an integer or a
1006 predicate. See Info node `(gnus)Customizing Articles'."
1007 :group 'gnus-article-treat
1008 :link '(custom-manual "(gnus)Customizing Articles")
1009 :type gnus-article-treat-head-custom)
1010 (put 'gnus-treat-buttonize-head 'highlight t)
1012 (defcustom gnus-treat-emphasize
1013 (and (or window-system
1017 Valid values are nil, t, `head', `first', `last', an integer or a
1018 predicate. See Info node `(gnus)Customizing Articles'."
1019 :group 'gnus-article-treat
1020 :link '(custom-manual "(gnus)Customizing Articles")
1021 :type gnus-article-treat-custom)
1022 (put 'gnus-treat-emphasize 'highlight t)
1024 (defcustom gnus-treat-strip-cr nil
1025 "Remove carriage returns.
1026 Valid values are nil, t, `head', `first', `last', an integer or a
1027 predicate. See Info node `(gnus)Customizing Articles'."
1029 :group 'gnus-article-treat
1030 :link '(custom-manual "(gnus)Customizing Articles")
1031 :type gnus-article-treat-custom)
1033 (defcustom gnus-treat-unsplit-urls nil
1034 "Remove newlines from within URLs.
1035 Valid values are nil, t, `head', `first', `last', an integer or a
1036 predicate. See Info node `(gnus)Customizing Articles'."
1038 :group 'gnus-article-treat
1039 :link '(custom-manual "(gnus)Customizing Articles")
1040 :type gnus-article-treat-custom)
1042 (defcustom gnus-treat-leading-whitespace nil
1043 "Remove leading whitespace in headers.
1044 Valid values are nil, t, `head', `first', `last', an integer or a
1045 predicate. See Info node `(gnus)Customizing Articles'."
1047 :group 'gnus-article-treat
1048 :link '(custom-manual "(gnus)Customizing Articles")
1049 :type gnus-article-treat-custom)
1051 (defcustom gnus-treat-hide-headers 'head
1053 Valid values are nil, t, `head', `first', `last', an integer or a
1054 predicate. See Info node `(gnus)Customizing Articles'."
1055 :group 'gnus-article-treat
1056 :link '(custom-manual "(gnus)Customizing Articles")
1057 :type gnus-article-treat-head-custom)
1059 (defcustom gnus-treat-hide-boring-headers nil
1060 "Hide boring headers.
1061 Valid values are nil, t, `head', `first', `last', an integer or a
1062 predicate. See Info node `(gnus)Customizing Articles'."
1063 :group 'gnus-article-treat
1064 :link '(custom-manual "(gnus)Customizing Articles")
1065 :type gnus-article-treat-head-custom)
1067 (defcustom gnus-treat-hide-signature nil
1068 "Hide the signature.
1069 Valid values are nil, t, `head', `first', `last', an integer or a
1070 predicate. See Info node `(gnus)Customizing Articles'."
1071 :group 'gnus-article-treat
1072 :link '(custom-manual "(gnus)Customizing Articles")
1073 :type gnus-article-treat-custom)
1075 (defcustom gnus-treat-fill-article nil
1077 Valid values are nil, t, `head', `first', `last', an integer or a
1078 predicate. See Info node `(gnus)Customizing Articles'."
1079 :group 'gnus-article-treat
1080 :link '(custom-manual "(gnus)Customizing Articles")
1081 :type gnus-article-treat-custom)
1083 (defcustom gnus-treat-hide-citation nil
1085 Valid values are nil, t, `head', `first', `last', an integer or a
1086 predicate. See Info node `(gnus)Customizing Articles'."
1087 :group 'gnus-article-treat
1088 :link '(custom-manual "(gnus)Customizing Articles")
1089 :type gnus-article-treat-custom)
1091 (defcustom gnus-treat-hide-citation-maybe nil
1093 Valid values are nil, t, `head', `first', `last', an integer or a
1094 predicate. See Info node `(gnus)Customizing Articles'."
1095 :group 'gnus-article-treat
1096 :link '(custom-manual "(gnus)Customizing Articles")
1097 :type gnus-article-treat-custom)
1099 (defcustom gnus-treat-strip-list-identifiers 'head
1100 "Strip list identifiers from `gnus-list-identifiers`.
1101 Valid values are nil, t, `head', `first', `last', an integer or a
1102 predicate. See Info node `(gnus)Customizing Articles'."
1104 :group 'gnus-article-treat
1105 :link '(custom-manual "(gnus)Customizing Articles")
1106 :type gnus-article-treat-custom)
1108 (make-obsolete-variable 'gnus-treat-strip-pgp
1109 "This option is obsolete in Gnus 5.10.")
1111 (defcustom gnus-treat-strip-pem nil
1112 "Strip PEM signatures.
1113 Valid values are nil, t, `head', `first', `last', an integer or a
1114 predicate. See Info node `(gnus)Customizing Articles'."
1115 :group 'gnus-article-treat
1116 :link '(custom-manual "(gnus)Customizing Articles")
1117 :type gnus-article-treat-custom)
1119 (defcustom gnus-treat-strip-banner t
1120 "Strip banners from articles.
1121 The banner to be stripped is specified in the `banner' group parameter.
1122 Valid values are nil, t, `head', `first', `last', an integer or a
1123 predicate. See Info node `(gnus)Customizing Articles'."
1124 :group 'gnus-article-treat
1125 :link '(custom-manual "(gnus)Customizing Articles")
1126 :type gnus-article-treat-custom)
1128 (defcustom gnus-treat-highlight-headers 'head
1129 "Highlight the headers.
1130 Valid values are nil, t, `head', `first', `last', an integer or a
1131 predicate. See Info node `(gnus)Customizing Articles'."
1132 :group 'gnus-article-treat
1133 :link '(custom-manual "(gnus)Customizing Articles")
1134 :type gnus-article-treat-head-custom)
1135 (put 'gnus-treat-highlight-headers 'highlight t)
1137 (defcustom gnus-treat-highlight-citation t
1138 "Highlight cited text.
1139 Valid values are nil, t, `head', `first', `last', an integer or a
1140 predicate. See Info node `(gnus)Customizing Articles'."
1141 :group 'gnus-article-treat
1142 :link '(custom-manual "(gnus)Customizing Articles")
1143 :type gnus-article-treat-custom)
1144 (put 'gnus-treat-highlight-citation 'highlight t)
1146 (defcustom gnus-treat-date-ut nil
1147 "Display the Date in UT (GMT).
1148 Valid values are nil, t, `head', `first', `last', an integer or a
1149 predicate. See Info node `(gnus)Customizing Articles'."
1150 :group 'gnus-article-treat
1151 :link '(custom-manual "(gnus)Customizing Articles")
1152 :type gnus-article-treat-head-custom)
1154 (defcustom gnus-treat-date-local nil
1155 "Display the Date in the local timezone.
1156 Valid values are nil, t, `head', `first', `last', an integer or a
1157 predicate. See Info node `(gnus)Customizing Articles'."
1158 :group 'gnus-article-treat
1159 :link '(custom-manual "(gnus)Customizing Articles")
1160 :type gnus-article-treat-head-custom)
1162 (defcustom gnus-treat-date-english nil
1163 "Display the Date in a format that can be read aloud in English.
1164 Valid values are nil, t, `head', `first', `last', an integer or a
1165 predicate. See Info node `(gnus)Customizing Articles'."
1167 :group 'gnus-article-treat
1168 :link '(custom-manual "(gnus)Customizing Articles")
1169 :type gnus-article-treat-head-custom)
1171 (defcustom gnus-treat-date-lapsed nil
1172 "Display the Date header in a way that says how much time has elapsed.
1173 Valid values are nil, t, `head', `first', `last', an integer or a
1174 predicate. See Info node `(gnus)Customizing Articles'."
1175 :group 'gnus-article-treat
1176 :link '(custom-manual "(gnus)Customizing Articles")
1177 :type gnus-article-treat-head-custom)
1179 (defcustom gnus-treat-date-original nil
1180 "Display the date in the original timezone.
1181 Valid values are nil, t, `head', `first', `last', an integer or a
1182 predicate. See Info node `(gnus)Customizing Articles'."
1183 :group 'gnus-article-treat
1184 :link '(custom-manual "(gnus)Customizing Articles")
1185 :type gnus-article-treat-head-custom)
1187 (defcustom gnus-treat-date-iso8601 nil
1188 "Display the date in the ISO8601 format.
1189 Valid values are nil, t, `head', `first', `last', an integer or a
1190 predicate. See Info node `(gnus)Customizing Articles'."
1192 :group 'gnus-article-treat
1193 :link '(custom-manual "(gnus)Customizing Articles")
1194 :type gnus-article-treat-head-custom)
1196 (defcustom gnus-treat-date-user-defined nil
1197 "Display the date in a user-defined format.
1198 The format is defined by the `gnus-article-time-format' variable.
1199 Valid values are nil, t, `head', `first', `last', an integer or a
1200 predicate. See Info node `(gnus)Customizing Articles'."
1201 :group 'gnus-article-treat
1202 :link '(custom-manual "(gnus)Customizing Articles")
1203 :type gnus-article-treat-head-custom)
1205 (defcustom gnus-treat-strip-headers-in-body t
1206 "Strip the X-No-Archive header line from the beginning of the body.
1207 Valid values are nil, t, `head', `first', `last', an integer or a
1208 predicate. See Info node `(gnus)Customizing Articles'."
1210 :group 'gnus-article-treat
1211 :link '(custom-manual "(gnus)Customizing Articles")
1212 :type gnus-article-treat-custom)
1214 (defcustom gnus-treat-strip-trailing-blank-lines nil
1215 "Strip trailing blank lines.
1216 Valid values are nil, t, `head', `first', `last', an integer or a
1217 predicate. See Info node `(gnus)Customizing Articles'.
1219 When set to t, it also strips trailing blanks in all MIME parts.
1220 Consider to use `last' instead."
1221 :group 'gnus-article-treat
1222 :link '(custom-manual "(gnus)Customizing Articles")
1223 :type gnus-article-treat-custom)
1225 (defcustom gnus-treat-strip-leading-blank-lines nil
1226 "Strip leading blank lines.
1227 Valid values are nil, t, `head', `first', `last', an integer or a
1228 predicate. See Info node `(gnus)Customizing Articles'.
1230 When set to t, it also strips trailing blanks in all MIME parts."
1231 :group 'gnus-article-treat
1232 :link '(custom-manual "(gnus)Customizing Articles")
1233 :type gnus-article-treat-custom)
1235 (defcustom gnus-treat-strip-multiple-blank-lines nil
1236 "Strip multiple blank lines.
1237 Valid values are nil, t, `head', `first', `last', an integer or a
1238 predicate. See Info node `(gnus)Customizing Articles'."
1239 :group 'gnus-article-treat
1240 :link '(custom-manual "(gnus)Customizing Articles")
1241 :type gnus-article-treat-custom)
1243 (defcustom gnus-treat-unfold-headers 'head
1244 "Unfold folded header lines.
1245 Valid values are nil, t, `head', `first', `last', an integer or a
1246 predicate. See Info node `(gnus)Customizing Articles'."
1248 :group 'gnus-article-treat
1249 :link '(custom-manual "(gnus)Customizing Articles")
1250 :type gnus-article-treat-custom)
1252 (defcustom gnus-treat-fold-headers nil
1254 Valid values are nil, t, `head', `first', `last', an integer or a
1255 predicate. See Info node `(gnus)Customizing Articles'."
1257 :group 'gnus-article-treat
1258 :link '(custom-manual "(gnus)Customizing Articles")
1259 :type gnus-article-treat-custom)
1261 (defcustom gnus-treat-fold-newsgroups 'head
1262 "Fold the Newsgroups and Followup-To headers.
1263 Valid values are nil, t, `head', `first', `last', an integer or a
1264 predicate. See Info node `(gnus)Customizing Articles'."
1266 :group 'gnus-article-treat
1267 :link '(custom-manual "(gnus)Customizing Articles")
1268 :type gnus-article-treat-custom)
1270 (defcustom gnus-treat-overstrike t
1271 "Treat overstrike highlighting.
1272 Valid values are nil, t, `head', `first', `last', an integer or a
1273 predicate. See Info node `(gnus)Customizing Articles'."
1274 :group 'gnus-article-treat
1275 :link '(custom-manual "(gnus)Customizing Articles")
1276 :type gnus-article-treat-custom)
1277 (put 'gnus-treat-overstrike 'highlight t)
1279 (defcustom gnus-treat-ansi-sequences (if (locate-library "ansi-color") t)
1280 "Treat ANSI SGR control sequences.
1281 Valid values are nil, t, `head', `first', `last', an integer or a
1282 predicate. See Info node `(gnus)Customizing Articles'."
1283 :group 'gnus-article-treat
1284 :link '(custom-manual "(gnus)Customizing Articles")
1285 :type gnus-article-treat-custom)
1287 (make-obsolete-variable 'gnus-treat-display-xface
1288 'gnus-treat-display-x-face)
1290 (defcustom gnus-treat-display-x-face
1291 (and (not noninteractive)
1292 (or (and (fboundp 'image-type-available-p)
1293 (image-type-available-p 'xbm)
1294 (string-match "^0x" (shell-command-to-string "uncompface"))
1295 (executable-find "icontopbm"))
1296 (and (featurep 'xemacs)
1299 "Display X-Face headers.
1300 Valid values are nil, t, `head', `first', `last', an integer or a
1301 predicate. See Info node `(gnus)Customizing Articles' and Info
1302 node `(gnus)X-Face' for details."
1303 :group 'gnus-article-treat
1305 :link '(custom-manual "(gnus)Customizing Articles")
1306 :link '(custom-manual "(gnus)X-Face")
1307 :type gnus-article-treat-head-custom
1308 :set (lambda (symbol value)
1311 (cond ((or (boundp symbol) (get symbol 'saved-value))
1313 ((boundp 'gnus-treat-display-xface)
1315 ** gnus-treat-display-xface is an obsolete variable;\
1316 use gnus-treat-display-x-face instead")
1317 (default-value 'gnus-treat-display-xface))
1318 ((get 'gnus-treat-display-xface 'saved-value)
1320 ** gnus-treat-display-xface is an obsolete variable;\
1321 use gnus-treat-display-x-face instead")
1322 (eval (car (get 'gnus-treat-display-xface 'saved-value))))
1325 (put 'gnus-treat-display-x-face 'highlight t)
1327 (defcustom gnus-treat-display-face
1328 (and (not noninteractive)
1329 (or (and (fboundp 'image-type-available-p)
1330 (image-type-available-p 'png))
1331 (and (featurep 'xemacs)
1334 "Display Face headers.
1335 Valid values are nil, t, `head', `first', `last', an integer or a
1336 predicate. See Info node `(gnus)Customizing Articles' and Info
1337 node `(gnus)X-Face' for details."
1338 :group 'gnus-article-treat
1340 :link '(custom-manual "(gnus)Customizing Articles")
1341 :link '(custom-manual "(gnus)X-Face")
1342 :type gnus-article-treat-head-custom)
1343 (put 'gnus-treat-display-face 'highlight t)
1345 (defcustom gnus-treat-display-smileys
1346 (if (or (and (featurep 'xemacs)
1348 (and (fboundp 'image-type-available-p)
1349 (image-type-available-p 'pbm)))
1352 Valid values are nil, t, `head', `first', `last', an integer or a
1353 predicate. See Info node `(gnus)Customizing Articles' and Info
1354 node `(gnus)Smileys' for details."
1355 :group 'gnus-article-treat
1357 :link '(custom-manual "(gnus)Customizing Articles")
1358 :link '(custom-manual "(gnus)Smileys")
1359 :type gnus-article-treat-custom)
1360 (put 'gnus-treat-display-smileys 'highlight t)
1362 (defcustom gnus-treat-from-picon
1363 (if (and (gnus-image-type-available-p 'xpm)
1364 (gnus-picons-installed-p))
1366 "Display picons in the From header.
1367 Valid values are nil, t, `head', `first', `last', an integer or a
1368 predicate. See Info node `(gnus)Customizing Articles' and Info
1369 node `(gnus)Picons' for details."
1371 :group 'gnus-article-treat
1373 :link '(custom-manual "(gnus)Customizing Articles")
1374 :link '(custom-manual "(gnus)Picons")
1375 :type gnus-article-treat-head-custom)
1376 (put 'gnus-treat-from-picon 'highlight t)
1378 (defcustom gnus-treat-mail-picon
1379 (if (and (gnus-image-type-available-p 'xpm)
1380 (gnus-picons-installed-p))
1382 "Display picons in To and Cc headers.
1383 Valid values are nil, t, `head', `first', `last', an integer or a
1384 predicate. See Info node `(gnus)Customizing Articles' and Info
1385 node `(gnus)Picons' for details."
1387 :group 'gnus-article-treat
1389 :link '(custom-manual "(gnus)Customizing Articles")
1390 :link '(custom-manual "(gnus)Picons")
1391 :type gnus-article-treat-head-custom)
1392 (put 'gnus-treat-mail-picon 'highlight t)
1394 (defcustom gnus-treat-newsgroups-picon
1395 (if (and (gnus-image-type-available-p 'xpm)
1396 (gnus-picons-installed-p))
1398 "Display picons in the Newsgroups and Followup-To headers.
1399 Valid values are nil, t, `head', `first', `last', an integer or a
1400 predicate. See Info node `(gnus)Customizing Articles' and Info
1401 node `(gnus)Picons' for details."
1403 :group 'gnus-article-treat
1405 :link '(custom-manual "(gnus)Customizing Articles")
1406 :link '(custom-manual "(gnus)Picons")
1407 :type gnus-article-treat-head-custom)
1408 (put 'gnus-treat-newsgroups-picon 'highlight t)
1410 (defcustom gnus-treat-body-boundary
1411 (if (and (eq window-system 'x)
1412 (or gnus-treat-newsgroups-picon
1413 gnus-treat-mail-picon
1414 gnus-treat-from-picon))
1416 "Draw a boundary at the end of the headers.
1417 Valid values are nil and `head'.
1418 See Info node `(gnus)Customizing Articles' for details."
1420 :group 'gnus-article-treat
1421 :link '(custom-manual "(gnus)Customizing Articles")
1422 :type gnus-article-treat-head-custom)
1424 (defcustom gnus-treat-capitalize-sentences nil
1425 "Capitalize sentence-starting words.
1426 Valid values are nil, t, `head', `first', `last', an integer or a
1427 predicate. See Info node `(gnus)Customizing Articles'."
1429 :group 'gnus-article-treat
1430 :link '(custom-manual "(gnus)Customizing Articles")
1431 :type gnus-article-treat-custom)
1433 (defcustom gnus-treat-wash-html nil
1435 Valid values are nil, t, `head', `first', `last', an integer or a
1436 predicate. See Info node `(gnus)Customizing Articles'."
1438 :group 'gnus-article-treat
1439 :link '(custom-manual "(gnus)Customizing Articles")
1440 :type gnus-article-treat-custom)
1442 (defcustom gnus-treat-fill-long-lines nil
1444 Valid values are nil, t, `head', `first', `last', an integer or a
1445 predicate. See Info node `(gnus)Customizing Articles'."
1446 :group 'gnus-article-treat
1447 :link '(custom-manual "(gnus)Customizing Articles")
1448 :type gnus-article-treat-custom)
1450 (defcustom gnus-treat-play-sounds nil
1452 Valid values are nil, t, `head', `first', `last', an integer or a
1453 predicate. See Info node `(gnus)Customizing Articles'."
1455 :group 'gnus-article-treat
1456 :link '(custom-manual "(gnus)Customizing Articles")
1457 :type gnus-article-treat-custom)
1459 (defcustom gnus-treat-translate nil
1460 "Translate articles from one language to another.
1461 Valid values are nil, t, `head', `first', `last', an integer or a
1462 predicate. See Info node `(gnus)Customizing Articles'."
1464 :group 'gnus-article-treat
1465 :link '(custom-manual "(gnus)Customizing Articles")
1466 :type gnus-article-treat-custom)
1468 (defcustom gnus-treat-x-pgp-sig nil
1470 To automatically treat X-PGP-Sig, set it to head.
1471 Valid values are nil, t, `head', `first', `last', an integer or a
1472 predicate. See Info node `(gnus)Customizing Articles'."
1474 :group 'gnus-article-treat
1475 :group 'mime-security
1476 :link '(custom-manual "(gnus)Customizing Articles")
1477 :type gnus-article-treat-custom)
1479 (defvar gnus-article-encrypt-protocol-alist
1480 '(("PGP" . mml2015-self-encrypt)))
1482 ;; Set to nil if more than one protocol added to
1483 ;; gnus-article-encrypt-protocol-alist.
1484 (defcustom gnus-article-encrypt-protocol "PGP"
1485 "The protocol used for encrypt articles.
1486 It is a string, such as \"PGP\". If nil, ask user."
1489 :group 'mime-security)
1491 (defvar gnus-article-wash-function nil
1492 "Function used for converting HTML into text.")
1494 (defcustom gnus-use-idna (and (condition-case nil (require 'idna) (file-error))
1495 (mm-coding-system-p 'utf-8)
1496 (executable-find idna-program))
1497 "Whether IDNA decoding of headers is used when viewing messages.
1498 This requires GNU Libidn, and by default only enabled if it is found."
1500 :group 'gnus-article-headers
1503 (defcustom gnus-article-over-scroll nil
1504 "If non-nil, allow scrolling the article buffer even when there no more text."
1506 :group 'gnus-article
1509 ;;; Internal variables
1511 (defvar gnus-english-month-names
1512 '("January" "February" "March" "April" "May" "June" "July" "August"
1513 "September" "October" "November" "December"))
1515 (defvar gnus-button-regexp nil)
1516 (defvar gnus-button-marker-list nil)
1517 ;; Regexp matching any of the regexps from `gnus-button-alist'.
1519 (defvar gnus-button-last nil)
1520 ;; The value of `gnus-button-alist' when `gnus-button-regexp' was build.
1522 (defvar article-goto-body-goes-to-point-min-p nil)
1523 (defvar gnus-article-wash-types nil)
1524 (defvar gnus-article-emphasis-alist nil)
1525 (defvar gnus-article-image-alist nil)
1527 (defvar gnus-article-mime-handle-alist-1 nil)
1528 (defvar gnus-treatment-function-alist
1529 '((gnus-treat-x-pgp-sig gnus-article-verify-x-pgp-sig)
1530 (gnus-treat-strip-banner gnus-article-strip-banner)
1531 (gnus-treat-strip-headers-in-body gnus-article-strip-headers-in-body)
1532 (gnus-treat-highlight-signature gnus-article-highlight-signature)
1533 (gnus-treat-buttonize gnus-article-add-buttons)
1534 (gnus-treat-fill-article gnus-article-fill-cited-article)
1535 (gnus-treat-fill-long-lines gnus-article-fill-long-lines)
1536 (gnus-treat-strip-cr gnus-article-remove-cr)
1537 (gnus-treat-unsplit-urls gnus-article-unsplit-urls)
1538 (gnus-treat-date-ut gnus-article-date-ut)
1539 (gnus-treat-date-local gnus-article-date-local)
1540 (gnus-treat-date-english gnus-article-date-english)
1541 (gnus-treat-date-original gnus-article-date-original)
1542 (gnus-treat-date-user-defined gnus-article-date-user)
1543 (gnus-treat-date-iso8601 gnus-article-date-iso8601)
1544 (gnus-treat-date-lapsed gnus-article-date-lapsed)
1545 (gnus-treat-display-x-face gnus-article-display-x-face)
1546 (gnus-treat-display-face gnus-article-display-face)
1547 (gnus-treat-hide-headers gnus-article-maybe-hide-headers)
1548 (gnus-treat-hide-boring-headers gnus-article-hide-boring-headers)
1549 (gnus-treat-hide-signature gnus-article-hide-signature)
1550 (gnus-treat-strip-list-identifiers gnus-article-hide-list-identifiers)
1551 (gnus-treat-leading-whitespace gnus-article-remove-leading-whitespace)
1552 (gnus-treat-strip-pem gnus-article-hide-pem)
1553 (gnus-treat-from-picon gnus-treat-from-picon)
1554 (gnus-treat-mail-picon gnus-treat-mail-picon)
1555 (gnus-treat-newsgroups-picon gnus-treat-newsgroups-picon)
1556 (gnus-treat-highlight-headers gnus-article-highlight-headers)
1557 (gnus-treat-highlight-signature gnus-article-highlight-signature)
1558 (gnus-treat-strip-trailing-blank-lines
1559 gnus-article-remove-trailing-blank-lines)
1560 (gnus-treat-strip-leading-blank-lines
1561 gnus-article-strip-leading-blank-lines)
1562 (gnus-treat-strip-multiple-blank-lines
1563 gnus-article-strip-multiple-blank-lines)
1564 (gnus-treat-overstrike gnus-article-treat-overstrike)
1565 (gnus-treat-ansi-sequences gnus-article-treat-ansi-sequences)
1566 (gnus-treat-unfold-headers gnus-article-treat-unfold-headers)
1567 (gnus-treat-fold-headers gnus-article-treat-fold-headers)
1568 (gnus-treat-fold-newsgroups gnus-article-treat-fold-newsgroups)
1569 (gnus-treat-buttonize-head gnus-article-add-buttons-to-head)
1570 (gnus-treat-display-smileys gnus-treat-smiley)
1571 (gnus-treat-capitalize-sentences gnus-article-capitalize-sentences)
1572 (gnus-treat-wash-html gnus-article-wash-html)
1573 (gnus-treat-emphasize gnus-article-emphasize)
1574 (gnus-treat-hide-citation gnus-article-hide-citation)
1575 (gnus-treat-hide-citation-maybe gnus-article-hide-citation-maybe)
1576 (gnus-treat-highlight-citation gnus-article-highlight-citation)
1577 (gnus-treat-body-boundary gnus-article-treat-body-boundary)
1578 (gnus-treat-play-sounds gnus-earcon-display)))
1580 (defvar gnus-article-mime-handle-alist nil)
1581 (defvar article-lapsed-timer nil)
1582 (defvar gnus-article-current-summary nil)
1584 (defvar gnus-article-mode-syntax-table
1585 (let ((table (copy-syntax-table text-mode-syntax-table)))
1586 ;; This causes the citation match run O(2^n).
1587 ;; (modify-syntax-entry ?- "w" table)
1588 (modify-syntax-entry ?> ")<" table)
1589 (modify-syntax-entry ?< "(>" table)
1590 ;; make M-. in article buffers work for `foo' strings
1591 (modify-syntax-entry ?' " " table)
1592 (modify-syntax-entry ?` " " table)
1594 "Syntax table used in article mode buffers.
1595 Initialized from `text-mode-syntax-table.")
1597 (defvar gnus-save-article-buffer nil)
1599 (defvar gnus-article-mode-line-format-alist
1600 (nconc '((?w (gnus-article-wash-status) ?s)
1601 (?m (gnus-article-mime-part-status) ?s))
1602 gnus-summary-mode-line-format-alist))
1604 (defvar gnus-number-of-articles-to-be-saved nil)
1606 (defvar gnus-inhibit-hiding nil)
1608 (defvar gnus-article-edit-mode nil)
1610 ;;; Macros for dealing with the article buffer.
1612 (defmacro gnus-with-article-headers (&rest forms)
1614 (set-buffer gnus-article-buffer)
1616 (let ((inhibit-read-only t)
1617 (inhibit-point-motion-hooks t)
1618 (case-fold-search t))
1619 (article-narrow-to-head)
1622 (put 'gnus-with-article-headers 'lisp-indent-function 0)
1623 (put 'gnus-with-article-headers 'edebug-form-spec '(body))
1625 (defmacro gnus-with-article-buffer (&rest forms)
1627 (set-buffer gnus-article-buffer)
1628 (let ((inhibit-read-only t))
1631 (put 'gnus-with-article-buffer 'lisp-indent-function 0)
1632 (put 'gnus-with-article-buffer 'edebug-form-spec '(body))
1634 (defun gnus-article-goto-header (header)
1635 "Go to HEADER, which is a regular expression."
1636 (re-search-forward (concat "^\\(" header "\\):") nil t))
1638 (defsubst gnus-article-hide-text (b e props)
1639 "Set text PROPS on the B to E region, extending `intangible' 1 past B."
1640 (gnus-add-text-properties-when 'article-type nil b e props)
1641 (when (memq 'intangible props)
1643 (max (1- b) (point-min))
1644 b 'intangible (cddr (memq 'intangible props)))))
1646 (defsubst gnus-article-unhide-text (b e)
1647 "Remove hidden text properties from region between B and E."
1648 (remove-text-properties b e gnus-hidden-properties)
1649 (when (memq 'intangible gnus-hidden-properties)
1650 (put-text-property (max (1- b) (point-min))
1651 b 'intangible nil)))
1653 (defun gnus-article-hide-text-type (b e type)
1654 "Hide text of TYPE between B and E."
1655 (gnus-add-wash-type type)
1656 (gnus-article-hide-text
1657 b e (cons 'article-type (cons type gnus-hidden-properties))))
1659 (defun gnus-article-unhide-text-type (b e type)
1660 "Unhide text of TYPE between B and E."
1661 (gnus-delete-wash-type type)
1662 (remove-text-properties
1663 b e (cons 'article-type (cons type gnus-hidden-properties)))
1664 (when (memq 'intangible gnus-hidden-properties)
1665 (put-text-property (max (1- b) (point-min))
1666 b 'intangible nil)))
1668 (defun gnus-article-hide-text-of-type (type)
1669 "Hide text of TYPE in the current buffer."
1671 (let ((b (point-min))
1673 (while (setq b (text-property-any b e 'article-type type))
1674 (add-text-properties b (incf b) gnus-hidden-properties)))))
1676 (defun gnus-article-delete-text-of-type (type)
1677 "Delete text of TYPE in the current buffer."
1679 (let ((b (point-min)))
1680 (if (eq type 'multipart)
1681 ;; Remove MIME buttons associated with multipart/alternative parts.
1684 (while (if (get-text-property (point) 'gnus-part)
1686 (when (setq b (next-single-property-change (point)
1691 (skip-chars-forward "\n")
1692 (when (eq (get-text-property b 'article-type) 'multipart)
1693 (delete-region b (point)))))
1694 (while (setq b (text-property-any b (point-max) 'article-type type))
1696 b (or (text-property-not-all b (point-max) 'article-type type)
1699 (defun gnus-article-delete-invisible-text ()
1700 "Delete all invisible text in the current buffer."
1702 (let ((b (point-min)))
1703 (while (setq b (text-property-any b (point-max) 'invisible t))
1705 b (or (text-property-not-all b (point-max) 'invisible t)
1708 (defun gnus-article-text-type-exists-p (type)
1709 "Say whether any text of type TYPE exists in the buffer."
1710 (text-property-any (point-min) (point-max) 'article-type type))
1712 (defsubst gnus-article-header-rank ()
1713 "Give the rank of the string HEADER as given by `gnus-sorted-header-list'."
1714 (let ((list gnus-sorted-header-list)
1717 (if (looking-at (car list))
1719 (setq list (cdr list))
1723 (defun article-hide-headers (&optional arg delete)
1724 "Hide unwanted headers and possibly sort them as well."
1726 ;; This function might be inhibited.
1727 (unless gnus-inhibit-hiding
1728 (let ((inhibit-read-only nil)
1729 (case-fold-search t)
1730 (max (1+ (length gnus-sorted-header-list)))
1731 (inhibit-point-motion-hooks t)
1732 (cur (current-buffer))
1733 ignored visible beg)
1735 ;; `gnus-ignored-headers' and `gnus-visible-headers' may be
1736 ;; group parameters, so we should go to the summary buffer.
1739 (progn (set-buffer gnus-summary-buffer) t)
1741 (setq ignored (when (not gnus-visible-headers)
1742 (cond ((stringp gnus-ignored-headers)
1743 gnus-ignored-headers)
1744 ((listp gnus-ignored-headers)
1745 (mapconcat 'identity
1746 gnus-ignored-headers
1748 visible (cond ((stringp gnus-visible-headers)
1749 gnus-visible-headers)
1750 ((and gnus-visible-headers
1751 (listp gnus-visible-headers))
1752 (mapconcat 'identity
1753 gnus-visible-headers
1757 ;; First we narrow to just the headers.
1758 (article-narrow-to-head)
1759 ;; Hide any "From " lines at the beginning of (mail) articles.
1760 (while (looking-at "From ")
1763 (delete-region (point-min) (point)))
1764 ;; Then treat the rest of the header lines.
1765 ;; Then we use the two regular expressions
1766 ;; `gnus-ignored-headers' and `gnus-visible-headers' to
1767 ;; select which header lines is to remain visible in the
1769 (while (re-search-forward "^[^ \t:]*:" nil t)
1771 ;; Mark the rank of the header.
1773 (point) (1+ (point)) 'message-rank
1774 (if (or (and visible (looking-at visible))
1776 (not (looking-at ignored))))
1777 (gnus-article-header-rank)
1780 (message-sort-headers-1)
1781 (when (setq beg (text-property-any
1782 (point-min) (point-max) 'message-rank (+ 2 max)))
1783 ;; We delete the unwanted headers.
1784 (gnus-add-wash-type 'headers)
1785 (add-text-properties (point-min) (+ 5 (point-min))
1786 '(article-type headers dummy-invisible t))
1787 (delete-region beg (point-max))))))))
1789 (defun article-hide-boring-headers (&optional arg)
1790 "Toggle hiding of headers that aren't very interesting.
1791 If given a negative prefix, always show; if given a positive prefix,
1793 (interactive (gnus-article-hidden-arg))
1794 (when (and (not (gnus-article-check-hidden-text 'boring-headers arg))
1795 (not gnus-show-all-headers))
1798 (let ((inhibit-read-only t)
1799 (inhibit-point-motion-hooks t))
1800 (article-narrow-to-head)
1801 (dolist (elem gnus-boring-article-headers)
1802 (goto-char (point-min))
1804 ;; Hide empty headers.
1806 (while (re-search-forward "^[^: \t]+:[ \t]*\n[^ \t]" nil t)
1808 (gnus-article-hide-text-type
1812 (if (re-search-forward "^[^ \t]" nil t)
1816 ;; Hide boring Newsgroups header.
1817 ((eq elem 'newsgroups)
1818 (when (gnus-string-equal
1819 (gnus-fetch-field "newsgroups")
1820 (gnus-group-real-name
1821 (if (boundp 'gnus-newsgroup-name)
1824 (gnus-article-hide-header "newsgroups")))
1825 ((eq elem 'to-address)
1826 (let ((to (message-fetch-field "to"))
1828 (gnus-parameter-to-address
1829 (if (boundp 'gnus-newsgroup-name)
1830 gnus-newsgroup-name ""))))
1831 (when (and to to-address
1834 ;; only one address in To
1835 (nth 1 (mail-extract-address-components to))
1837 (gnus-article-hide-header "to"))))
1839 (let ((to (message-fetch-field "to"))
1841 (gnus-parameter-to-list
1842 (if (boundp 'gnus-newsgroup-name)
1843 gnus-newsgroup-name ""))))
1844 (when (and to to-list
1847 ;; only one address in To
1848 (nth 1 (mail-extract-address-components to))
1850 (gnus-article-hide-header "to"))))
1852 (let ((cc (message-fetch-field "cc"))
1854 (gnus-parameter-to-list
1855 (if (boundp 'gnus-newsgroup-name)
1856 gnus-newsgroup-name ""))))
1857 (when (and cc to-list
1860 ;; only one address in CC
1861 (nth 1 (mail-extract-address-components cc))
1863 (gnus-article-hide-header "cc"))))
1864 ((eq elem 'followup-to)
1865 (when (gnus-string-equal
1866 (message-fetch-field "followup-to")
1867 (message-fetch-field "newsgroups"))
1868 (gnus-article-hide-header "followup-to")))
1869 ((eq elem 'reply-to)
1870 (if (gnus-group-find-parameter
1871 gnus-newsgroup-name 'broken-reply-to)
1872 (gnus-article-hide-header "reply-to")
1873 (let ((from (message-fetch-field "from"))
1874 (reply-to (message-fetch-field "reply-to")))
1881 (lambda (x) (downcase (cadr x)))
1882 (mail-extract-address-components from t))
1885 (lambda (x) (downcase (cadr x)))
1886 (mail-extract-address-components reply-to t))
1888 (gnus-article-hide-header "reply-to")))))
1890 (let ((date (message-fetch-field "date")))
1892 (< (days-between (current-time-string) date)
1894 (gnus-article-hide-header "date"))))
1896 (let ((to (message-fetch-field "to"))
1897 (cc (message-fetch-field "cc")))
1898 (when (> (length to) 1024)
1899 (gnus-article-hide-header "to"))
1900 (when (> (length cc) 1024)
1901 (gnus-article-hide-header "cc"))))
1905 (goto-char (point-min))
1906 (while (re-search-forward "^to:" nil t)
1907 (setq to-count (1+ to-count)))
1908 (when (> to-count 1)
1909 (while (> to-count 0)
1910 (goto-char (point-min))
1912 (re-search-forward "^to:" nil nil to-count)
1914 (narrow-to-region (point) (point-max))
1915 (gnus-article-hide-header "to"))
1916 (setq to-count (1- to-count))))
1917 (goto-char (point-min))
1918 (while (re-search-forward "^cc:" nil t)
1919 (setq cc-count (1+ cc-count)))
1920 (when (> cc-count 1)
1921 (while (> cc-count 0)
1922 (goto-char (point-min))
1924 (re-search-forward "^cc:" nil nil cc-count)
1926 (narrow-to-region (point) (point-max))
1927 (gnus-article-hide-header "cc"))
1928 (setq cc-count (1- cc-count)))))))))))))
1930 (defun gnus-article-hide-header (header)
1932 (goto-char (point-min))
1933 (when (re-search-forward (concat "^" header ":") nil t)
1934 (gnus-article-hide-text-type
1938 (if (re-search-forward "^[^ \t]" nil t)
1943 (defvar gnus-article-normalized-header-length 40
1944 "Length of normalized headers.")
1946 (defun article-normalize-headers ()
1947 "Make all header lines 40 characters long."
1949 (let ((inhibit-read-only t)
1953 (article-narrow-to-head)
1956 ((< (setq column (- (point-at-eol) (point)))
1957 gnus-article-normalized-header-length)
1959 (insert (make-string
1960 (- gnus-article-normalized-header-length column)
1962 ((> column gnus-article-normalized-header-length)
1963 (gnus-put-text-property
1965 (forward-char gnus-article-normalized-header-length)