+2002-10-17 TSUCHIYA Masatoshi <tsuchiya@namazu.org>
+
+ * nnheader.el (nnheader-parse-naked-head): New function.
+ (nnheader-parse-head): Use the above function, in order to handle
+ continuation lines properly.
+ (nnheader-remove-body): New function.
+ (nnheader-remove-cr-followed-by-lf): New function.
+ (nnheader-ms-strip-cr): Use the above function.
+
+ * gnus-agent.el (gnus-agent-regenerate-group): Call
+ `nnheader-remove-body'; use `nnheader-parse-naked-head' instead of
+ `nnheader-parse-head'.
+ * gnus-cache.el (gnus-cache-possibly-enter-article): Ditto.
+
+ * gnus-msg.el (gnus-inews-yank-articles): Do not unfold
+ continuation lines by itself; call `nnheader-parse-naked-head'
+ instead of `nnheader-parse-head'.
+ * nndiary.el (nndiary-parse-head): Ditto.
+ * nnfolder.el (nnfolder-parse-head): Ditto.
+ * nnimap.el (nnimap-retrieve-headers-progress): Ditto.
+ * nnmaildir.el (nnmaildir--update-nov): Ditto.
+ * nnml.el (nnml-parse-head): Ditto.
+
+2002-10-17 Steve Youngs <youngs@xemacs.org>
+
+ * gnus-art.el (gnus-button-man-handler): Add 'manual-entry' for
+ XEmacs, default to it if featurep 'xemacs.
+
2002-10-16 Katsumi Yamaoka <yamaoka@jpl.org>
* spam-stat.el: Check for the existence of hash functions instead
(mm-with-unibyte-buffer
(nnheader-insert-file-contents
(concat dir (number-to-string (car arts))))
- (goto-char (point-min))
- (if (search-forward "\n\n" nil t)
- (delete-region (point) (point-max))
- (goto-char (point-max)))
- (setq header (nnheader-parse-head t)))
+ (nnheader-remove-body)
+ (setq header (nnheader-parse-naked-head)))
(mail-header-set-number header (car arts))
(nnheader-insert-nov header)
(setq changed t)
:group 'gnus-article-buttons
:type 'regexp)
-(defcustom gnus-button-man-handler 'man
+(defcustom gnus-button-man-handler (if (featurep 'xemacs)
+ 'manual-entry
+ 'man)
"Function to use for displaying man pages.
The function must take at least one argument with a string naming the
man page."
- :type '(choice (function-item :tag "Man" man)
+ :type '(choice (function-item :tag "Man (Emacs)" man)
+ (function-item :tag "Man (XEmacs)" manual-entry)
(function-item :tag "Woman" woman)
(function :tag "Other"))
:group 'gnus-article-buttons)
(when (> (buffer-size) 0)
(gnus-write-buffer-as-coding-system
gnus-cache-write-file-coding-system file)
- (setq headers (nnheader-parse-head t))
+ (nnheader-remove-body)
+ (setq headers (nnheader-parse-naked-head))
(mail-header-set-number headers number)
(gnus-cache-change-buffer group)
(set-buffer (cdr gnus-cache-buffer))
(with-current-buffer gnus-article-copy
(save-restriction
(nnheader-narrow-to-headers)
- (ietf-drums-unfold-fws)
- (nnheader-parse-head t)))))
+ (nnheader-parse-naked-head)))))
(message-yank-original)
(setq beg (or beg (mark t))))
(when articles
(narrow-to-region
(goto-char (point-min))
(if (search-forward "\n\n" nil t) (1- (point)) (point-max))))
- ;; Fold continuation lines.
- (goto-char (point-min))
- (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
- (replace-match " " t t))
- ;; Remove any tabs; they are too confusing.
- (subst-char-in-region (point-min) (point-max) ?\t ? )
- (let ((headers (nnheader-parse-head t)))
+ (let ((headers (nnheader-parse-naked-head)))
(mail-header-set-chars headers chars)
(mail-header-set-number headers number)
headers))))
(if (search-forward "\n\n" e t) (setq e (1- (point)))))
(with-temp-buffer
(insert-buffer-substring buf b e)
- ;; Fold continuation lines.
- (goto-char (point-min))
- (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
- (replace-match " " t t))
- ;; Remove any tabs; they are too confusing.
- (subst-char-in-region (point-min) (point-max) ?\t ? )
- (let ((headers (nnheader-parse-head t)))
+ (let ((headers (nnheader-parse-naked-head)))
(mail-header-set-chars headers chars)
(mail-header-set-number headers number)
headers)))))
;; Parsing headers and NOV lines.
+(defsubst nnheader-remove-cr-followed-by-lf ()
+ (goto-char (point-max))
+ (while (search-backward "\r\n" nil t)
+ (delete-char 1)))
+
(defsubst nnheader-header-value ()
(let ((pt (point)))
(prog2
(buffer-substring (point) (std11-field-end))
(goto-char pt))))
-(defun nnheader-parse-head (&optional naked)
+(defun nnheader-parse-naked-head (&optional number)
+ ;; This function unfolds continuation lines in this buffer
+ ;; destructively. When this side effect is unwanted, use
+ ;; `nnheader-parse-head' instead of this function.
(let ((case-fold-search t)
- (cur (current-buffer))
(buffer-read-only nil)
- in-reply-to lines p ref)
- (goto-char (point-min))
- (when naked
- (insert "\n"))
- ;; Search to the beginning of the next header. Error messages
- ;; do not begin with 2 or 3.
+ (cur (current-buffer))
+ (p (point-min))
+ in-reply-to lines ref)
+ (nnheader-remove-cr-followed-by-lf)
+ (ietf-drums-unfold-fws)
+ (subst-char-in-region (point-min) (point-max) ?\t ? )
+ (goto-char p)
+ (insert "\n")
(prog1
- (when (or naked (re-search-forward "^[23][0-9]+ " nil t))
- ;; This implementation of this function, with nine
- ;; search-forwards instead of the one re-search-forward and
- ;; a case (which basically was the old function) is actually
- ;; about twice as fast, even though it looks messier. You
- ;; can't have everything, I guess. Speed and elegance
- ;; don't always go hand in hand.
- (make-full-mail-header
- ;; Number.
- (if naked
- (progn
- (setq p (point-min))
- 0)
- (prog1
- (read cur)
- (end-of-line)
- (setq p (point))
- (narrow-to-region (point)
- (or (and (search-forward "\n.\n" nil t)
- (- (point) 2))
- (point)))))
- ;; Subject.
- (progn
- (goto-char p)
- (if (search-forward "\nsubject:" nil t)
- (nnheader-header-value) "(none)"))
- ;; From.
- (progn
- (goto-char p)
- (if (search-forward "\nfrom:" nil t)
- (nnheader-header-value) "(nobody)"))
- ;; Date.
- (progn
- (goto-char p)
- (if (search-forward "\ndate:" nil t)
- (nnheader-header-value) ""))
- ;; Message-ID.
- (progn
- (goto-char p)
- (if (search-forward "\nmessage-id:" nil t)
- (buffer-substring
- (1- (or (search-forward "<" (gnus-point-at-eol) t)
- (point)))
- (or (search-forward ">" (gnus-point-at-eol) t) (point)))
- ;; If there was no message-id, we just fake one to make
- ;; subsequent routines simpler.
- (nnheader-generate-fake-message-id)))
- ;; References.
- (progn
- (goto-char p)
- (if (search-forward "\nreferences:" nil t)
- (nnheader-header-value)
- ;; Get the references from the in-reply-to header if there
- ;; were no references and the in-reply-to header looks
- ;; promising.
- (if (and (search-forward "\nin-reply-to:" nil t)
- (setq in-reply-to (nnheader-header-value))
- (string-match "<[^\n>]+>" in-reply-to))
- (let (ref2)
- (setq ref (substring in-reply-to (match-beginning 0)
- (match-end 0)))
- (while (string-match "<[^\n>]+>"
- in-reply-to (match-end 0))
- (setq ref2 (substring in-reply-to (match-beginning 0)
- (match-end 0)))
- (when (> (length ref2) (length ref))
- (setq ref ref2)))
- ref)
- nil)))
- ;; Chars.
- 0
- ;; Lines.
- (progn
- (goto-char p)
- (if (search-forward "\nlines: " nil t)
- (if (numberp (setq lines (read cur)))
- lines 0)
- 0))
- ;; Xref.
- (progn
- (goto-char p)
- (and (search-forward "\nxref:" nil t)
- (nnheader-header-value)))
-
- ;; Extra.
- (when nnmail-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)))))
+ ;; This implementation of this function, with nine
+ ;; search-forwards instead of the one re-search-forward and a
+ ;; case (which basically was the old function) is actually
+ ;; about twice as fast, even though it looks messier. You
+ ;; can't have everything, I guess. Speed and elegance don't
+ ;; always go hand in hand.
+ (make-full-mail-header
+ ;; Number.
+ (or number 0)
+ ;; Subject.
+ (progn
+ (goto-char p)
+ (if (search-forward "\nsubject:" nil t)
+ (nnheader-header-value) "(none)"))
+ ;; From.
+ (progn
+ (goto-char p)
+ (if (search-forward "\nfrom:" nil t)
+ (nnheader-header-value) "(nobody)"))
+ ;; Date.
+ (progn
+ (goto-char p)
+ (if (search-forward "\ndate:" nil t)
+ (nnheader-header-value) ""))
+ ;; Message-ID.
+ (progn
+ (goto-char p)
+ (if (search-forward "\nmessage-id:" nil t)
+ (buffer-substring
+ (1- (or (search-forward "<" (gnus-point-at-eol) t)
+ (point)))
+ (or (search-forward ">" (gnus-point-at-eol) t) (point)))
+ ;; If there was no message-id, we just fake one to make
+ ;; subsequent routines simpler.
+ (nnheader-generate-fake-message-id)))
+ ;; References.
+ (progn
+ (goto-char p)
+ (if (search-forward "\nreferences:" nil t)
+ (nnheader-header-value)
+ ;; Get the references from the in-reply-to header if
+ ;; there were no references and the in-reply-to header
+ ;; looks promising.
+ (if (and (search-forward "\nin-reply-to:" nil t)
+ (setq in-reply-to (nnheader-header-value))
+ (string-match "<[^\n>]+>" in-reply-to))
+ (let (ref2)
+ (setq ref (substring in-reply-to (match-beginning 0)
+ (match-end 0)))
+ (while (string-match "<[^\n>]+>"
+ in-reply-to (match-end 0))
+ (setq ref2 (substring in-reply-to (match-beginning 0)
+ (match-end 0)))
+ (when (> (length ref2) (length ref))
+ (setq ref ref2)))
+ ref)
+ nil)))
+ ;; Chars.
+ 0
+ ;; Lines.
+ (progn
+ (goto-char p)
+ (if (search-forward "\nlines: " nil t)
+ (if (numberp (setq lines (read cur)))
+ lines 0)
+ 0))
+ ;; Xref.
+ (progn
+ (goto-char p)
+ (and (search-forward "\nxref:" nil t)
+ (nnheader-header-value)))
+ ;; Extra.
+ (when nnmail-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)))
+ (goto-char p)
+ (delete-char 1))))
+
+(defun nnheader-parse-head (&optional naked)
+ (let ((cur (current-buffer)) num beg end)
+ (when (if naked
+ (setq num 0
+ beg (point-min)
+ end (point-max))
+ (goto-char (point-min))
+ ;; Search to the beginning of the next header. Error
+ ;; messages do not begin with 2 or 3.
+ (when (re-search-forward "^[23][0-9]+ " nil t)
+ (end-of-line)
+ (setq num (read cur)
+ beg (point)
+ end (if (search-forward "\n.\n" nil t)
+ (- (point) 2)
+ (point)))))
+ (with-temp-buffer
+ (insert-buffer-substring cur beg end)
+ (nnheader-parse-naked-head num)))))
(defmacro nnheader-nov-skip-field ()
'(search-forward "\t" eol 'move))
(point-max)))
(goto-char (point-min)))
+(defun nnheader-remove-body ()
+ "Remove the body from an article in this current buffer."
+ (goto-char (point-min))
+ (when (or (search-forward "\n\n" nil t)
+ (search-forward "\n\r\n" nil t))
+ (delete-region (point) (point-max))))
+
(defun nnheader-set-temp-buffer (name &optional noerase)
"Set-buffer to an empty (possibly new) buffer called NAME with undo disabled."
(set-buffer (get-buffer-create name))
(defun nnheader-ms-strip-cr ()
"Strip ^M from the end of all lines."
(save-excursion
- (goto-char (point-min))
- (while (re-search-forward "\r$" nil t)
- (delete-backward-char 1))))
+ (nnheader-remove-cr-followed-by-lf)))
(defun nnheader-file-size (file)
"Return the file size of FILE or 0."
(with-temp-buffer
(buffer-disable-undo)
(insert headers)
- (nnheader-fold-continuation-lines)
- (subst-char-in-region (point-min) (point-max) ?\t ? )
- (nnheader-ms-strip-cr)
- (nnheader-fold-continuation-lines)
- (subst-char-in-region (point-min) (point-max) ?\t ? )
- (let ((head (nnheader-parse-head 'naked)))
+ (let ((head (nnheader-parse-naked-head)))
(mail-header-set-number head uid)
(mail-header-set-chars head chars)
(mail-header-set-lines head lines)
(setq nov-mid 0))
(goto-char (point-min))
(delete-char 1)
- (nnheader-fold-continuation-lines)
- (setq nov (nnheader-parse-head 'naked)
+ (setq nov (nnheader-parse-naked-head)
field (or (mail-header-lines nov) 0)))
(unless (or (zerop field) (nnmaildir--param pgname 'distrust-Lines:))
(setq nov-mid field))
(unless (zerop (buffer-size))
(narrow-to-region
(goto-char (point-min))
- (if (re-search-forward "\n\r?\n" nil t) (1- (point)) (point-max))))
- ;; Fold continuation lines.
- (goto-char (point-min))
- (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
- (replace-match " " t t))
- ;; Remove any tabs; they are too confusing.
- (subst-char-in-region (point-min) (point-max) ?\t ? )
- ;; Remove any ^M's; they are too confusing.
- (subst-char-in-region (point-min) (point-max) ?\r ? )
- (let ((headers (nnheader-parse-head t)))
+ (if (search-forward "\n\n" nil t)
+ (1- (point))
+ (if (search-forward "\n\r\n" nil t)
+ (- (point) 2)
+ (point-max)))))
+ (let ((headers (nnheader-parse-naked-head)))
(mail-header-set-chars headers chars)
(mail-header-set-number headers number)
headers))))
+2002-10-17 Kai Gro\e,A_\e(Bjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
+
+ * gnus.texi (Other Marks): Document gnus-downloadable-mark and
+ gnus-undownloaded-mark. Adapted idea from Sriram Karra
+ <karra@shakti.homelinux.net>.
+ (Formatting Fonts): Say that guillemets are wrong. (How to enter
+ guillemets in Texinfo files?)
+
2002-10-12 Simon Josefsson <jas@extundo.com>
* message.texi (Movement): Add.
\e$B$9\e(B (@code{gnus-unseen-mark})\e$B!#\e(B@code{gnus-recent-mark} \e$B$H8+Hf$Y$F2<$5$$!#\e(B
@item
+@vindex gnus-undownloaded-mark
+gnus \e$B%(!<%8%'%s%H\e(B @pxref{Agent Basics} \e$B$r;H$C$F$$$k$H$-!"$$$/$D$+$N5-;v\e(B
+\e$B$O%@%&%s%m!<%I$5$l$F$$$J$$$+$b$7$l$^$;$s!#%*%U%i%$%s\e(B (unplugged) \e$B$N>uBV\e(B
+\e$B$G$O$=$N$h$&$J5-;v$r8+$k$3$H$,$G$-$^$;$s!#$=$l$i$N5-;v$K$O:G=i$N7e\e(B
+\e$B$K\e(B @samp{@@} \e$B$N0u$,IU$-$^$9!#\e(B(\e$BJQ?t\e(B @code{gnus-undownloaded-mark} \e$B$G$I$N\e(B
+\e$BJ8;z$r;H$&$+$r@)8f$7$^$9!#\e(B)
+
+@item
+@vindex gnus-downloadable-mark
+gnus \e$B%(!<%8%'%s%H\e(B @pxref{Agent Basics} \e$B$O$$$/$D$+$N5-;v$r<+F0E*$K%@%&%s\e(B
+\e$B%m!<%I$7$^$9$,!"<+F0E*$K%@%&%s%m!<%I$5$l$J$$5-;v$K$b%@%&%s%m!<%I$N$?$a$N\e(B
+\e$BL@<(E*$J0u$rIU$1$k$3$H$O2DG=$G$9!#$=$N$h$&$JL@<(E*$K0u$,IU$1$i$l$?5-;v$K\e(B
+\e$B$O!":G=i$N7e$K\e(B @samp{%} \e$B$N0u$,IU$-$^$9!#\e(B(\e$BJQ\e(B
+\e$B?t\e(B @code{gnus-downloadable-mark} \e$B$G$I$NJ8;z$r;H$&$+$r@)8f$7$^$9!#\e(B)
+
+@item
@vindex gnus-not-empty-thread-mark
@vindex gnus-empty-thread-mark
\e$B$b$7\e(B @samp{%e} \e$B$N;EMM$,;H$o$l$k$H!"%9%l%C%I$,$"$k$+$I$&$+$O!";07eL\\e(B
\e$B%7%s%\%k$N$I$A$i$+$G$"$kI,MW$,$"$j$^$9!#%^%&%9$,%W%m%Q%F%#$N@_Dj$5$l$F$$\e(B
\e$B$k%F%-%9%H$N>e$rDL2a$9$k$H!"%P%k!<%s%&%#%s%I%&$,8=$l$F!"J8;zNs$rI=<($7$^\e(B
\e$B$9!#$3$l$N>\$7$$>pJs$O\e(B @ref{(emacs)Help Echo} (GNU Emacs) \e$B$^$?\e(B
-\e$B$O\e(B @code{balloon-help-mode} (XEmacs) \e$B$N@bL@J8;zNs$r;2>H$7$F$/$@$5$$!#\e(B
+\e$B$O\e(B @code{balloon-help-mode} (XEmacs) \e$B$N@bL@J8;zNs$r;2>H$7$F$/$@$5$$!#\e(B(\e$B5;\e(B
+\e$B=QE*$JM}M3$N$?$a$K!"%.%#%a\e(B (guillemets: @footnote{guillemets (\e$BJ)8l\e(B) \e$B$O%.%e\e(B
+\e$B%a$H$bI=5-$5$l$^$9!#F|K\8l$N!V!W$KEv$?$k$b$N$G!"8}F,I=8=$rI=5-$7$?$j!"6/\e(B
+\e$BD4$7$?$$C18l$r0O$`!"2?$+$+$i$N0zMQItJ,$r0O$`!"=qJ*Ey$N%?%$%H%k$r5-$9EyMM!9\e(B
+\e$B$K;H$o$l$^$9!#\e(B}) \e$B$O$3$N@a$G$O\e(B @samp{<<} \e$B$*$h$S\e(B @samp{>>} \e$B$H$7$F6a;w$5$l\e(B
+\e$B$^$7$?!#\e(B)
\e$B$3$l$O%0%k!<%W%P%C%U%!$NBeBX<jK!$G$9\e(B:
Compare with @code{gnus-recent-mark}.
@item
+@vindex gnus-undownloaded-mark
+When using the Gnus agent @pxref{Agent Basics}, some articles might not
+have been downloaded. Such articles cannot be viewed while you are
+offline (unplugged). These articles get the @samp{@@} mark in the
+first column. (The variable @code{gnus-undownloaded-mark} controls
+which character to use.)
+
+@item
+@vindex gnus-downloadable-mark
+The Gnus agent @pxref{Agent Basics} downloads some articles
+automatically, but it is also possible to explicitly mark articles for
+download, even if they would not be downloaded automatically. Such
+explicitly-marked articles get the @samp{%} mark in the first column.
+(The variable @code{gnus-downloadable-mark} controls which character to
+use.)
+
+@item
@vindex gnus-not-empty-thread-mark
@vindex gnus-empty-thread-mark
If the @samp{%e} spec is used, the presence of threads or not will be
over text with this property set, a balloon window will appear and
display the string. Please refer to @ref{(emacs)Help Echo} (in GNU
Emacs) or the doc string of @code{balloon-help-mode} (in XEmacs) for
-more information on this.
+more information on this. (For technical reasons, the guillemets have
+been approximated as @samp{<<} and @samp{>>} in this paragraph.)
Here's an alternative recipe for the group buffer: