*** pub/pgnus/lisp/gnus-art.el Sat Oct 24 07:45:02 1998 --- pgnus/lisp/gnus-art.el Sat Oct 24 20:35:25 1998 *************** *** 1019,1025 **** (widen) (forward-line 1) (narrow-to-region (point) (point-max)) ! (when (or (not ct) (equal (car ctl) "text/plain")) (mm-decode-body charset (and cte (intern (downcase --- 1019,1025 ---- (widen) (forward-line 1) (narrow-to-region (point) (point-max)) ! (when (or (not ctl) (equal (car ctl) "text/plain")) (mm-decode-body charset (and cte (intern (downcase *************** *** 1045,1057 **** (and type (string-match "quoted-printable" (downcase type)))) (goto-char (point-min)) (search-forward "\n\n" nil 'move) ! (quoted-printable-decode-region (point) (point-max)) ! (when mm-default-coding-system ! (mm-decode-body mm-default-coding-system)))))) ! ! (defun article-mime-decode-quoted-printable-buffer () ! "Decode Quoted-Printable in the current buffer." ! (quoted-printable-decode-region (point-min) (point-max))) (defun article-hide-pgp (&optional arg) "Toggle hiding of any PGP headers and signatures in the current article. --- 1045,1055 ---- (and type (string-match "quoted-printable" (downcase type)))) (goto-char (point-min)) (search-forward "\n\n" nil 'move) ! (save-restriction ! (narrow-to-region (point) (point-max)) ! (quoted-printable-decode-region (point-min) (point-max)) ! (when mm-default-coding-system ! (mm-decode-body mm-default-coding-system))))))) (defun article-hide-pgp (&optional arg) "Toggle hiding of any PGP headers and signatures in the current article. *** pub/pgnus/lisp/gnus-cache.el Sun Oct 11 02:32:02 1998 --- pgnus/lisp/gnus-cache.el Sat Oct 24 20:35:25 1998 *************** *** 201,217 **** (beginning-of-line)) (forward-line 1)) (beginning-of-line) ! ;; [number subject from date id references chars lines xref] ! (insert (format "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t\n" ! (mail-header-number headers) ! (mail-header-subject headers) ! (mail-header-from headers) ! (mail-header-date headers) ! (mail-header-id headers) ! (or (mail-header-references headers) "") ! (or (mail-header-chars headers) "") ! (or (mail-header-lines headers) "") ! (or (mail-header-xref headers) ""))) ;; Update the active info. (set-buffer gnus-summary-buffer) (gnus-cache-update-active group number) --- 201,207 ---- (beginning-of-line)) (forward-line 1)) (beginning-of-line) ! (nnheader-insert-nov headers) ;; Update the active info. (set-buffer gnus-summary-buffer) (gnus-cache-update-active group number) *** pub/pgnus/lisp/gnus-msg.el Tue Oct 20 00:27:05 1998 --- pgnus/lisp/gnus-msg.el Sat Oct 24 20:35:25 1998 *************** *** 395,401 **** ;; Delete the headers from the displayed articles. (set-buffer gnus-article-copy) (delete-region (goto-char (point-min)) ! (or (search-forward "\n\n" nil t) (point))) ;; Insert the original article headers. (insert-buffer-substring gnus-original-article-buffer beg end) (article-decode-encoded-words))) --- 395,401 ---- ;; Delete the headers from the displayed articles. (set-buffer gnus-article-copy) (delete-region (goto-char (point-min)) ! (or (search-forward "\n\n" nil t) (point-max))) ;; Insert the original article headers. (insert-buffer-substring gnus-original-article-buffer beg end) (article-decode-encoded-words))) *** pub/pgnus/lisp/gnus-sum.el Sat Oct 24 07:45:05 1998 --- pgnus/lisp/gnus-sum.el Sat Oct 24 20:35:26 1998 *************** *** 772,777 **** --- 772,787 ---- (defvar gnus-decode-encoded-word-function 'mail-decode-encoded-word-string "Variable that says which function should be used to decode a string with encoded words.") + (defcustom gnus-extra-headers nil + "*Extra headers to parse." + :group 'gnus-summary + :type '(repeat symbol)) + + (defcustom gnus-ignored-from-addresses nil + "*Regexp of From headers that may be suppressed in favor of To headers." + :group 'gnus-summary + :type 'regexp) + ;;; Internal variables (defvar gnus-article-mime-handles nil) *************** *** 832,837 **** --- 842,848 ---- (?l (bbb-grouplens-score gnus-tmp-header) ?s) (?V (gnus-thread-total-score (and (boundp 'thread) (car thread))) ?d) (?U gnus-tmp-unread ?c) + (?f (gnus-summary-from-or-to-or-newsgroups gnus-tmp-header) ?s) (?t (gnus-summary-number-of-articles-in-thread (and (boundp 'thread) (car thread)) gnus-tmp-level) ?d) *************** *** 2387,2393 **** (let ((gnus-summary-line-format-spec spec) (gnus-newsgroup-downloadable '((0 . t)))) (gnus-summary-insert-line ! [0 "" "" "" "" "" 0 0 ""] 0 nil 128 t nil "" nil 1) (goto-char (point-min)) (setq pos (list (cons 'unread (and (search-forward "\200" nil t) (- (point) 2))))) --- 2398,2404 ---- (let ((gnus-summary-line-format-spec spec) (gnus-newsgroup-downloadable '((0 . t)))) (gnus-summary-insert-line ! [0 "" "" "" "" "" 0 0 "" nil] 0 nil 128 t nil "" nil 1) (goto-char (point-min)) (setq pos (list (cons 'unread (and (search-forward "\200" nil t) (- (point) 2))))) *************** *** 2411,2416 **** --- 2422,2448 ---- (point) (progn (eval gnus-summary-dummy-line-format-spec) (point)) (list 'gnus-number gnus-tmp-number 'gnus-intangible gnus-tmp-number))) + (defun gnus-summary-from-or-to-or-newsgroups (header) + (let ((to (cdr (assq 'To (mail-header-extra header)))) + (newsgroups (cdr (assq 'Newsgroups (mail-header-extra header))))) + (cond + ((and to + gnus-ignored-from-addresses + (string-match gnus-ignored-from-addresses + (mail-header-from header))) + (or (car (funcall gnus-extract-address-components + (funcall gnus-decode-encoded-word-function to))) + (funcall gnus-decode-encoded-word-function to))) + ((and newsgroups + gnus-ignored-from-addresses + (string-match gnus-ignored-from-addresses + (mail-header-from header))) + newsgroups) + (t + (or (car (funcall gnus-extract-address-components + (mail-header-from header))) + (mail-header-from header)))))) + (defun gnus-summary-insert-line (gnus-tmp-header gnus-tmp-level gnus-tmp-current gnus-tmp-unread gnus-tmp-replied *************** *** 3057,3065 **** (setq heads nil))))) gnus-newsgroup-dependencies))) - ;; The following macros and functions were written by Felix Lee - ;; . - (defmacro gnus-nov-read-integer () '(prog1 (if (eq (char-after) ?\t) --- 3089,3094 ---- *************** *** 3075,3080 **** --- 3104,3119 ---- (defmacro gnus-nov-field () '(buffer-substring (point) (if (gnus-nov-skip-field) (1- (point)) eol))) + (defmacro gnus-nov-parse-extra () + '(let (out string) + (while (not (memq (char-after) '(?\n nil))) + (setq string (gnus-nov-field)) + (when (string-match "^\\([^ :]\\): " string) + (push (cons (intern (match-string 1)) + (substring string (match-end 0))) + out))) + out)) + ;; This function has to be called with point after the article number ;; on the beginning of the line. (defsubst gnus-nov-parse-line (number dependencies &optional force-new) *************** *** 3103,3109 **** (gnus-nov-read-integer) ; chars (gnus-nov-read-integer) ; lines (unless (eq (char-after) ?\n) ! (gnus-nov-field))))) ; misc (widen)) --- 3142,3149 ---- (gnus-nov-read-integer) ; chars (gnus-nov-read-integer) ; lines (unless (eq (char-after) ?\n) ! (gnus-nov-field)) ; misc ! (gnus-nov-parse-extra)))) ; extra (widen)) *************** *** 3579,3584 **** --- 3619,3630 ---- (defvar gnus-tmp-root-expunged nil) (defvar gnus-tmp-dummy-line nil) + (defvar gnus-tmp-header) + (defun gnus-extra-header (type &optional header) + "Return the extra header of TYPE." + (or (cdr (assq type (mail-header-extra (or header gnus-tmp-header)))) + "")) + (defun gnus-summary-prepare-threads (threads) "Prepare summary buffer from THREADS and indentation LEVEL. THREADS is either a list of `(PARENT [(CHILD1 [(GRANDCHILD ...]...) ...])' *************** *** 4517,4523 **** (progn (goto-char p) (and (search-forward "\nxref: " nil t) ! (nnheader-header-value))))) (when (equal id ref) (setq ref nil)) --- 4563,4581 ---- (progn (goto-char p) (and (search-forward "\nxref: " nil t) ! (nnheader-header-value))) ! ;; Extra. ! (when gnus-extra-headers ! (let ((extra gnus-extra-headers) ! out) ! (while extra ! (goto-char p) ! (when (search-forward ! (concat "\n" (symbol-name (car extra)) ": ") nil t) ! (push (cons (car extra) (nnheader-header-value)) ! out)) ! (pop extra)) ! out)))) (when (equal id ref) (setq ref nil)) *** pub/pgnus/lisp/gnus.el Sat Oct 24 07:45:05 1998 --- pgnus/lisp/gnus.el Sat Oct 24 20:35:26 1998 *************** *** 250,256 **** :link '(custom-manual "(gnus)Exiting Gnus") :group 'gnus) ! (defconst gnus-version-number "0.37" "Version number for this version of Gnus.") (defconst gnus-version (format "Pterodactyl Gnus v%s" gnus-version-number) --- 250,256 ---- :link '(custom-manual "(gnus)Exiting Gnus") :group 'gnus) ! (defconst gnus-version-number "0.38" "Version number for this version of Gnus.") (defconst gnus-version (format "Pterodactyl Gnus v%s" gnus-version-number) *************** *** 1811,1816 **** --- 1811,1817 ---- %a Extracted name of the poster (string) %A Extracted address of the poster (string) %F Contents of the From: header (string) + %f Contents of the From: or To: headers (string) %x Contents of the Xref: header (string) %D Date of the article (string) %d Date of the article (string) in DD-MMM format *** pub/pgnus/lisp/mm-util.el Sat Oct 24 07:45:06 1998 --- pgnus/lisp/mm-util.el Sat Oct 24 20:35:26 1998 *************** *** 222,228 **** (put 'mm-with-unibyte-buffer 'lisp-indent-function 0) (put 'mm-with-unibyte-buffer 'edebug-form-spec '(body)) - (provide 'mm-util) ;;; mm-util.el ends here --- 222,227 ---- *** pub/pgnus/lisp/mm-uu.el Sat Oct 24 07:45:06 1998 --- pgnus/lisp/mm-uu.el Sat Oct 24 20:35:27 1998 *************** *** 2,8 **** ;; Copyright (c) 1998 by Shenghuo Zhu ;; Author: Shenghuo Zhu ! ;; $Revision: 5.1 $ ;; Keywords: news postscript uudecode binhex shar ;; This file is not part of GNU Emacs, but the same permissions --- 2,8 ---- ;; Copyright (c) 1998 by Shenghuo Zhu ;; Author: Shenghuo Zhu ! ;; $Revision: 5.2 $ ;; Keywords: news postscript uudecode binhex shar ;; This file is not part of GNU Emacs, but the same permissions *** pub/pgnus/lisp/nnheader.el Sat Oct 24 07:45:07 1998 --- pgnus/lisp/nnheader.el Sat Oct 24 20:35:27 1998 *************** *** 140,153 **** "Set article xref of HEADER to xref." `(aset ,header 8 ,xref)) (defun make-mail-header (&optional init) "Create a new mail header structure initialized with INIT." ! (make-vector 9 init)) (defun make-full-mail-header (&optional number subject from date id ! references chars lines xref) "Create a new mail header structure initialized with the parameters given." ! (vector number subject from date id references chars lines xref)) ;; fake message-ids: generation and detection --- 140,162 ---- "Set article xref of HEADER to xref." `(aset ,header 8 ,xref)) + (defmacro mail-header-extra (header) + "Return the extra headers in HEADER." + `(aref ,header 9)) + + (defmacro mail-header-set-extra (header extra) + "Set the extra headers in HEADER to EXTRA." + `(aset ,header 9 ',extra)) + (defun make-mail-header (&optional init) "Create a new mail header structure initialized with INIT." ! (make-vector 10 init)) (defun make-full-mail-header (&optional number subject from date id ! references chars lines xref ! extra) "Create a new mail header structure initialized with the parameters given." ! (vector number subject from date id references chars lines xref extra)) ;; fake message-ids: generation and detection *************** *** 257,263 **** (progn (goto-char p) (and (search-forward "\nxref: " nil t) ! (nnheader-header-value))))) (when naked (goto-char (point-min)) (delete-char 1))))) --- 266,285 ---- (progn (goto-char p) (and (search-forward "\nxref: " nil t) ! (nnheader-header-value))) ! ! ;; Extra. ! (when gnus-extra-headers ! (let ((extra nnmail-extra-headers) ! out) ! (while extra ! (goto-char p) ! (when (search-forward ! (concat "\n" (symbol-name (car extra)) ": ") nil t) ! (push (cons (car extra) (nnheader-header-value)) ! out)) ! (pop extra)) ! out)))) (when naked (goto-char (point-min)) (delete-char 1))))) *************** *** 276,283 **** (if (numberp num) num 0))) (or (eobp) (forward-char 1)))) - ;; (defvar nnheader-none-counter 0) - (defun nnheader-parse-nov () (let ((eol (gnus-point-at-eol))) (vector --- 298,303 ---- *************** *** 310,317 **** (insert "\t") (princ (or (mail-header-lines header) 0) (current-buffer)) (insert "\t") ! (when (mail-header-xref header) (insert "Xref: " (mail-header-xref header) "\t")) (insert "\n")) (defun nnheader-insert-article-line (article) --- 330,343 ---- (insert "\t") (princ (or (mail-header-lines header) 0) (current-buffer)) (insert "\t") ! (when (or (mail-header-xref header) ! (mail-header-extra header)) (insert "Xref: " (mail-header-xref header) "\t")) + (when (mail-header-extra header) + (let ((extra (mail-header-extra header))) + (while extra + (insert (symbol-name (caar extra)) + ": " (cdar extra) "\t")))) (insert "\n")) (defun nnheader-insert-article-line (article) *** pub/pgnus/lisp/nnmail.el Sat Oct 24 07:45:07 1998 --- pgnus/lisp/nnmail.el Sat Oct 24 20:35:27 1998 *************** *** 449,454 **** --- 449,459 ---- (const warn) (const delete))) + (defcustom nnmail-extra-headers nil + "*Extra headers to parse." + :group 'nnmail + :type '(repeat symbol)) + ;;; Internal variables. (defvar nnmail-split-history nil *** pub/pgnus/lisp/qp.el Sat Oct 24 07:45:07 1998 --- pgnus/lisp/qp.el Sat Oct 24 20:35:27 1998 *************** *** 64,76 **** (save-excursion (save-restriction (narrow-to-region from to) (goto-char (point-min)) (while (and (skip-chars-forward (or class "^\000-\007\013\015-\037\200-\377=")) (not (eobp))) (insert (prog1 ! (upcase (format "=%x" (char-after (point)))) (delete-char 1)))) (when fold ;; Fold long lines. --- 64,77 ---- (save-excursion (save-restriction (narrow-to-region from to) + (mm-encode-body) (goto-char (point-min)) (while (and (skip-chars-forward (or class "^\000-\007\013\015-\037\200-\377=")) (not (eobp))) (insert (prog1 ! (upcase (format "=%x" (char-after))) (delete-char 1)))) (when fold ;; Fold long lines. *************** *** 85,91 **** (defun quoted-printable-encode-string (string) "QP-encode STRING and return the results." ! (with-temp-buffer (insert string) (quoted-printable-encode-region (point-min) (point-max)) (buffer-string))) --- 86,92 ---- (defun quoted-printable-encode-string (string) "QP-encode STRING and return the results." ! (mm-with-unibyte-buffer (insert string) (quoted-printable-encode-region (point-min) (point-max)) (buffer-string))) *** pub/pgnus/lisp/rfc1843.el Sat Oct 24 07:45:08 1998 --- pgnus/lisp/rfc1843.el Sat Oct 24 20:35:27 1998 *************** *** 2,8 **** ;; Copyright (c) 1998 by Shenghuo Zhu ;; Author: Shenghuo Zhu ! ;; $Revision: 5.1 $ ;; Keywords: news HZ ;; Time-stamp: --- 2,8 ---- ;; Copyright (c) 1998 by Shenghuo Zhu ;; Author: Shenghuo Zhu ! ;; $Revision: 5.2 $ ;; Keywords: news HZ ;; Time-stamp: *** pub/pgnus/lisp/ChangeLog Sat Oct 24 07:45:01 1998 --- pgnus/lisp/ChangeLog Sat Oct 24 20:35:24 1998 *************** *** 1,3 **** --- 1,47 ---- + Sat Oct 24 20:31:55 1998 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.38 is released. + + 1998-10-24 07:54:58 Lars Magne Ingebrigtsen + + * gnus-art.el (article-mime-decode-quoted-printable-buffer): + Removed. + (article-de-quoted-unreadable): Narrow to default. + + * qp.el (quoted-printable-encode-region): Encode before QP-ing. + + * gnus-art.el (article-decode-charset): Decode even when broken + MIME. + + * gnus-sum.el (gnus-summary-from-or-to-or-newsgroups): Return + name. + + * gnus-msg.el (gnus-copy-article-buffer): Delete headers. + + * gnus-cache.el (gnus-cache-possibly-enter-article): Use + nnheader. + + * nnmail.el (nnmail-extra-headers): New variable. + + * nnheader.el (nnheader-insert-nov): Insert extra. + + * gnus.el (gnus-summary-line-format): Doc fix. + + * gnus-sum.el (gnus-get-newsgroup-headers): Parse extra. + (gnus-nov-parse-line): Ditto. + (gnus-nov-parse-extra): New macro. + (gnus-header): New function. + (gnus-update-summary-mark-positions): Change. + (gnus-ignored-from-addresses): New variable. + (gnus-summary-insert-from-or-to): New function. + + * gnus.el (gnus-extra-headers): New variable. + + * nnheader.el (make-mail-header): Expand. + (mail-header-extra): New macro. + (mail-header-set-extra): Ditto. + (make-full-mail-header): Expand. + Sat Oct 24 07:41:42 1998 Lars Magne Ingebrigtsen * gnus.el: Pterodactyl Gnus v0.37 is released. *** pub/pgnus/texi/gnus.texi Sat Oct 24 07:45:09 1998 --- pgnus/texi/gnus.texi Sat Oct 24 20:35:29 1998 *************** *** 1,7 **** \input texinfo @c -*-texinfo-*- @setfilename gnus ! @settitle Pterodactyl Gnus 0.37 Manual @synindex fn cp @synindex vr cp @synindex pg cp --- 1,7 ---- \input texinfo @c -*-texinfo-*- @setfilename gnus ! @settitle Pterodactyl Gnus 0.38 Manual @synindex fn cp @synindex vr cp @synindex pg cp *************** *** 318,324 **** @tex @titlepage ! @title Pterodactyl Gnus 0.37 Manual @author by Lars Magne Ingebrigtsen @page --- 318,324 ---- @tex @titlepage ! @title Pterodactyl Gnus 0.38 Manual @author by Lars Magne Ingebrigtsen @page *************** *** 354,360 **** spool or your mbox file. All at the same time, if you want to push your luck. ! This manual corresponds to Pterodactyl Gnus 0.37. @end ifinfo --- 354,360 ---- spool or your mbox file. All at the same time, if you want to push your luck. ! This manual corresponds to Pterodactyl Gnus 0.38. @end ifinfo *************** *** 3253,3258 **** --- 3253,3259 ---- @menu * Summary Buffer Lines:: You can specify how summary lines should look. + * To From Newsgroups:: How to not display your own name. * Summary Buffer Mode Line:: You can say how the mode line should look. * Summary Highlighting:: Making the summary buffer all pretty and nice. @end menu *************** *** 3306,3311 **** --- 3307,3315 ---- Full @code{From} header. @item n The name (from the @code{From} header). + @item f + The name, code @code{To} header or the @code{Newsgroups} header + (@pxref{To From Newsgroups}). @item a The name (from the @code{From} header). This differs from the @code{n} spec in that it uses the function designated by the *************** *** 3393,3398 **** --- 3397,3465 ---- (Isn't that the case with everything, though? But I digress.) This restriction may disappear in later versions of Gnus. + + + @node To From Newsgroups + @subsection To From Newsgroups + @cindex To + @cindex Newsgroups + + In some groups (particularly in archive groups), the @code{From} header + isn't very interesting, since all the articles there are written by + you. To display the information in the @code{To} or @code{Newsgroups} + headers instead, you need to decide three things: What information to + gather; where to display it; and when to display it. + + @enumerate + @item + @vindex gnus-extra-headers + The reading of extra header information is controlled by the + @code{gnus-extra-headers}. This is a list of header symbols. For + instance: + + @lisp + (setq gnus-extra-headers + '(To Newsgroups X-Newsreader)) + @end lisp + + This will result in Gnus trying to obtain these three headers, and + storing it in header structures for later easy retrieval. + + @item + @findex gnus-extra-header + The value of these extra headers can be accessed via the + @code{gnus-extra-header} function. Here's a format line spec that will + access the @code{X-Newsreader} header: + + @example + "%~(form (gnus-extra-header 'X-Newsreader))@@" + @end example + + @item + @vindex gnus-ignored-from-addresses + The @code{gnus-ignored-from-addresses} variable says when the @samp{%f} + summary line spec returns the @code{To}, @code{Newsreader} or + @code{From} header. If this regexp matches the contents of the + @code{From} header, the value of the @code{To} or @code{Newsreader} + headers are used instead. + + @end enumerate + + @vindex nnmail-extra-headers + A related variable is @code{nnmail-extra-headers}, which controls when + to include extra headers when generating active files. + + In summary, you'd typically do something like the following: + + @lisp + (setq gnus-extra-headers + '(To Newsgroups)) + (setq nnmail-extra-headers gnus-extra-headers) + (setq gnus-summary-line-format + "%U%R%z%I%(%[%4L: %-20,20f%]%) %s\n") + (setq gnus-ignored-from-addresses + "Your Name Here") + @end lisp @node Summary Buffer Mode Line *** pub/pgnus/texi/message.texi Sat Oct 24 07:45:09 1998 --- pgnus/texi/message.texi Sat Oct 24 20:35:29 1998 *************** *** 1,7 **** \input texinfo @c -*-texinfo-*- @setfilename message ! @settitle Pterodactyl Message 0.37 Manual @synindex fn cp @synindex vr cp @synindex pg cp --- 1,7 ---- \input texinfo @c -*-texinfo-*- @setfilename message ! @settitle Pterodactyl Message 0.38 Manual @synindex fn cp @synindex vr cp @synindex pg cp *************** *** 42,48 **** @tex @titlepage ! @title Pterodactyl Message 0.37 Manual @author by Lars Magne Ingebrigtsen @page --- 42,48 ---- @tex @titlepage ! @title Pterodactyl Message 0.38 Manual @author by Lars Magne Ingebrigtsen @page *************** *** 83,89 **** * Key Index:: List of Message mode keys. @end menu ! This manual corresponds to Pterodactyl Message 0.37. Message is distributed with the Gnus distribution bearing the same version number as this manual. --- 83,89 ---- * Key Index:: List of Message mode keys. @end menu ! This manual corresponds to Pterodactyl Message 0.38. Message is distributed with the Gnus distribution bearing the same version number as this manual. *** pub/pgnus/texi/ChangeLog Tue Oct 20 00:27:12 1998 --- pgnus/texi/ChangeLog Sat Oct 24 20:35:29 1998 *************** *** 1,3 **** --- 1,9 ---- + 1998-10-24 08:37:12 Lars Magne Ingebrigtsen + + * gnus.texi (Summary Buffer Lines): Addition. + (To): New. + (To): Addition. + 1998-10-15 18:15:34 Simon Josefsson * gnus.texi (Group Info): Must be list of ranges. *** pub/pgnus/GNUS-NEWS Sun Oct 11 02:32:10 1998 --- pgnus/GNUS-NEWS Sat Oct 24 20:35:29 1998 *************** *** 3,5 **** --- 3,9 ---- *** gnus-auto-select-first can now be a function to be called to position point. + *** The user can now decide which extra headers should be included in + summary buffers and NOV files. + +