(require 'gnus-spec)
(require 'gnus-int)
(require 'browse-url)
+(require 'mm-bodies)
(defgroup gnus-article nil
"Article display."
:type 'regexp
:group 'gnus-article-various)
-(defcustom gnus-article-mode-line-format "Gnus: %%b %S"
+(defcustom gnus-article-mode-line-format "Gnus: %g %S"
"*The format specification for the article mode line.
See `gnus-summary-mode-line-format' for a closer description."
:type 'string
buffer-read-only)
(rfc2047-decode-region (point-min) (point-max)))))
+(defun gnus-article-decode-charset (&optional prompt)
+ "Decode charset-encoded text in the article.
+If PROMPT (the prefix), prompt for a coding system to use."
+ (interactive "P")
+ (save-excursion
+ (set-buffer gnus-article-buffer)
+ (let* ((inhibit-point-motion-hooks t)
+ (ct (message-fetch-field "Content-Type" t))
+ (cte (message-fetch-field "Content-Transfer-Encoding" t))
+ (charset (cond
+ (prompt
+ (mm-read-coding-system "Charset to decode: "))
+ (ct
+ (mm-content-type-charset ct))
+ (gnus-newsgroup-name
+ (gnus-group-find-parameter
+ gnus-newsgroup-name 'charset))))
+ buffer-read-only)
+ (save-restriction
+ (goto-char (point-min))
+ (search-forward "\n\n" nil 'move)
+ (narrow-to-region (point) (point-max))
+ (mm-decode-body
+ charset (and cte (intern (downcase (gnus-strip-whitespace cte)))))))))
+
(defalias 'gnus-decode-rfc1522 'article-decode-rfc1522)
(defalias 'gnus-article-decode-rfc1522 'article-decode-rfc1522)
(defun article-decode-rfc1522 ()
(buffer-disable-undo (current-buffer))
(setq buffer-read-only t)
(set-syntax-table gnus-article-mode-syntax-table)
- (when (fboundp 'set-buffer-multibyte)
- (set-buffer-multibyte t))
+ (mm-enable-multibyte)
(gnus-run-hooks 'gnus-article-mode-hook))
(defun gnus-article-setup-buffer ()
;;; Post news commands of Gnus group mode and summary mode
-(defun gnus-group-mail ()
- "Start composing a mail."
- (interactive)
- (gnus-setup-message 'message
- (message-mail)))
+(defun gnus-group-mail (&optional arg)
+ "Start composing a mail.
+If ARG, use the group under the point to find a posting style.
+If ARG is 1, prompt for a group name to find the posting style."
+ (interactive "P")
+ (let ((gnus-newsgroup-name
+ (if arg
+ (if (= 1 (prefix-numeric-value arg))
+ (completing-read "Use style of group: " gnus-active-hashtb nil
+ (gnus-read-active-file-p))
+ (gnus-group-group-name))
+ "")))
+ (gnus-setup-message 'message (message-mail))
+ ))
(defun gnus-group-post-news (&optional arg)
"Start composing a news message.
(buffer-disable-undo gnus-article-copy)
(save-excursion
(set-buffer gnus-article-copy)
- (when (fboundp 'set-buffer-multibyte)
- (set-buffer-multibyte t)))
+ (mm-enable-multibyte))
(let ((article-buffer (or article-buffer gnus-article-buffer))
end beg)
(if (not (and (get-buffer article-buffer)
:group 'gnus-threading
:type 'string)
-(defcustom gnus-summary-mode-line-format "Gnus: %%b [%A] %Z"
+(defcustom gnus-summary-mode-line-format "Gnus: %g [%A] %Z"
"*The format specification for the summary mode line.
It works along the same lines as a normal formatting string,
with some simple extensions:
"s" gnus-article-highlight-signature)
(gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
- "w" gnus-article-decode-mime-words)
+ "w" gnus-article-decode-mime-words
+ "c" gnus-article-decode-charset)
(gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
"z" gnus-article-date-ut
["Citation" gnus-article-highlight-citation t])
("MIME"
["Words" gnus-article-decode-mime-words t]
+ ["Charset" gnus-article-decode-charset t]
["QP" gnus-article-de-quoted-unreadable t])
("Date"
["Local" gnus-article-date-local t]
(make-local-hook 'pre-command-hook)
(add-hook 'pre-command-hook 'gnus-set-global-variables nil t)
(gnus-run-hooks 'gnus-summary-mode-hook)
+ (mm-enable-multibyte)
(gnus-update-format-specifications nil 'summary 'summary-mode 'summary-dummy)
(gnus-update-summary-mark-positions))
number dependencies force-new))))
(push header headers))
(forward-line 1))
- ;(error
- ; (gnus-error 4 "Strange nov line (%d)"
- ; (count-lines (point-min) (point))))
- )
+ (error
+ (gnus-error 4 "Strange nov line (%d)"
+ (count-lines (point-min) (point)))))
(forward-line 1))
;; A common bug in inn is that if you have posted an article and
;; then retrieves the active file, it will answer correctly --
(when (gnus-buffer-exists-p buf)
(kill-buffer buf))))
-(cond
- ((fboundp 'point-at-bol)
- (fset 'gnus-point-at-bol 'point-at-bol))
- ((fboundp 'line-beginning-position)
- (fset 'gnus-point-at-bol 'line-beginning-position))
- (t
- (defun gnus-point-at-bol ()
- "Return point at the beginning of the line."
- (let ((p (point)))
- (beginning-of-line)
- (prog1
- (point)
- (goto-char p))))))
-
-(cond
- ((fboundp 'point-at-eol)
- (fset 'gnus-point-at-eol 'point-at-eol))
- ((fboundp 'line-end-position)
- (fset 'gnus-point-at-eol 'line-end-position))
- (t
- (defun gnus-point-at-eol ()
- "Return point at the end of the line."
- (let ((p (point)))
- (end-of-line)
- (prog1
- (point)
- (goto-char p))))))
+(fset 'gnus-point-at-bol
+ (if (fboundp 'point-at-bol)
+ 'point-at-bol
+ 'line-beginning-position))
+
+(fset 'gnus-point-at-eol
+ (if (fboundp 'point-at-eol)
+ 'point-at-eol
+ 'line-end-position))
(defun gnus-delete-first (elt list)
"Delete by side effect the first occurrence of ELT as a member of LIST."
(erase-buffer))
(set-buffer (gnus-get-buffer-create gnus-work-buffer))
(kill-all-local-variables)
- (buffer-disable-undo (current-buffer))))
+ (mm-enable-multibyte)))
(defmacro gnus-group-real-name (group)
"Find the real name of a foreign newsgroup."
:link '(custom-manual "(gnus)Exiting Gnus")
:group 'gnus)
-(defconst gnus-version-number "0.10"
+(defconst gnus-version-number "0.13"
"Version number for this version of Gnus.")
(defconst gnus-version (format "Pterodactyl Gnus v%s" gnus-version-number)
(defcustom gnus-article-display-hook
(if (and (string-match "XEmacs" emacs-version)
(featurep 'xface))
- '(gnus-article-hide-headers-if-wanted
+ '(gnus-article-decode-charset
+ gnus-article-decode-rfc1522
+ gnus-article-hide-headers-if-wanted
gnus-article-hide-boring-headers
gnus-article-treat-overstrike
gnus-article-maybe-highlight
gnus-article-display-x-face)
- '(gnus-article-hide-headers-if-wanted
+ '(gnus-article-decode-charset
+ gnus-article-decode-rfc1522
+ gnus-article-hide-headers-if-wanted
gnus-article-hide-boring-headers
gnus-article-treat-overstrike
gnus-article-maybe-highlight))
(string-to-number
(if (zerop major)
(format "%s00%02d%02d"
- (cond
- ((member alpha '("(ding)" "d")) "4.99")
- ((member alpha '("September" "s")) "5.01")
- ((member alpha '("Red" "r")) "5.03")
- ((member alpha '("Quassia" "q")) "5.05")
- ((member alpha '("Pterodactyl" "p")) "5.07")
- ((member alpha '("o")) "5.09")
- ((member alpha '("n")) "5.11"))
+ (if (member alpha '("(ding)" "d"))
+ "4.99"
+ (+ 5 (* 0.02
+ (abs
+ (- (char-int (aref (downcase alpha) 0))
+ (char-int ?t))))
+ -0.01))
minor least)
(format "%d.%02d%02d" major minor least))))))
(require 'mail-abbrevs)
(require 'mailabbrev))
(require 'rfc2047)
+(require 'mm-bodies)
(defgroup message '((user-mail-address custom-variable)
(user-full-name custom-variable))
(erase-buffer))
(set-buffer (get-buffer-create " *message work*"))
(kill-all-local-variables)
- (buffer-disable-undo (current-buffer))))
+ (mm-enable-multibyte)))
(defun message-functionp (form)
"Return non-nil if FORM is funcallable."
(setq adaptive-fill-first-line-regexp
(concat "[ \t]*[-a-z0-9A-Z]*>+[ \t]*\\|"
adaptive-fill-first-line-regexp))
- (when (fboundp 'set-buffer-multibyte)
- (set-buffer-multibyte t))
+ (mm-enable-multibyte)
(run-hooks 'text-mode-hook 'message-mode-hook))
\f
(rfc2047-encode-message-header)
;; Let the user do all of the above.
(run-hooks 'message-header-hook))
+ (message-encode-message-body)
(unwind-protect
(save-excursion
(set-buffer tembuf)
(rfc2047-encode-message-header)
;; Let the user do all of the above.
(run-hooks 'message-header-hook))
+ (message-encode-message-body)
(message-cleanup-headers)
(if (not (message-check-news-syntax))
(progn
(y-or-n-p "Empty article. Really post? "))))
;; Check for control characters.
(message-check 'control-chars
- (if (re-search-forward "[\000-\007\013\015-\037\200-\237]" nil t)
+ (if (re-search-forward "[\000-\007\013\015-\032\034-\037\200-\237]" nil t)
(y-or-n-p
"The article contains control characters. Really post? ")
t))
(setq idx (1+ idx)))
string))
+;;;
+;;; MIME functions
+;;;
+
+(defun message-encode-message-body ()
+ "Examine the message body, encode it, and add the requisite headers."
+ (when (featurep 'mule)
+ (save-excursion
+ (save-restriction
+ (message-narrow-to-headers)
+ (message-remove-header
+ "^Content-Transfer-Encoding:\\|^Content-Type:\\|^Mime-Version:" t)
+ (goto-char (point-max))
+ (widen)
+ (narrow-to-region (point) (point-max))
+ (let* ((charset (mm-encode-body))
+ (encoding (mm-body-encoding)))
+ (when (consp charset)
+ (error "Can't encode messages with multiple charsets (yet)"))
+ (widen)
+ (message-narrow-to-headers)
+ (goto-char (point-max))
+ (mm-insert-rfc822-headers
+ (or charset (mm-mule-charset-to-mime-charset 'ascii))
+ encoding))))))
+
(run-hooks 'message-load-hook)
(provide 'message)
--- /dev/null
+;;; mm-bodies.el --- Functions for decoding MIME things
+;; Copyright (C) 1998 Free Software Foundation, Inc.
+
+;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
+;; MORIOKA Tomohiko <morioka@jaist.ac.jp>
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'mm-util)
+
+(defun mm-encode-body ()
+ "Encode a body.
+Should be called narrowed to the body that is to be encoded.
+If there is more than one non-ASCII MULE charset, then list of found
+MULE charsets are returned.
+If successful, the MIME charset is returned.
+If no encoding was done, nil is returned."
+ (save-excursion
+ (goto-char (point-min))
+ (let ((charsets
+ (delq 'ascii (find-charset-region (point-min) (point-max))))
+ charset)
+ (cond
+ ;; No encoding.
+ ((null charsets)
+ nil)
+ ;; Too many charsets.
+ ((> (length charsets) 1)
+ charsets)
+ ;; We encode.
+ (t
+ (let ((mime-charset (mm-mule-charset-to-mime-charset (car charsets)))
+ start)
+ (when (not (mm-coding-system-equal
+ mime-charset buffer-file-coding-system))
+ (while (not (eobp))
+ (if (eq (char-charset (following-char)) 'ascii)
+ (when start
+ (mm-encode-coding-region start (point) mime-charset)
+ (setq start nil))
+ (unless start
+ (setq start (point))))
+ (forward-char 1))
+ (when start
+ (mm-encode-coding-region start (point) mime-charset)
+ (setq start nil)))
+ mime-charset))))))
+
+(defun mm-body-encoding ()
+ "Return the encoding of the current buffer."
+ (if (null (delq 'ascii (find-charset-region (point-min) (point-max))))
+ '7bit
+ '8bit))
+
+;;;
+;;; Functions for decoding
+;;;
+
+(defun mm-decode-body (charset encoding)
+ "Decode the current article that has been encoded with ENCODING.
+The characters in CHARSET should then be decoded."
+ (save-excursion
+ (when encoding
+ (cond
+ ((eq encoding 'quoted-printable)
+ (quoted-printable-decode-region (point-min) (point-max)))
+ ((eq encoding 'base64)
+ (base64-decode-region (point-min) (point-max)))
+ ((memq encoding '(7bit 8bit binary))
+ )
+ (t
+ (error "Can't decode encoding %s" encoding))))
+ (when (featurep 'mule)
+ (let (mule-charset)
+ (when (and charset
+ (setq mule-charset (mm-charset-to-coding-system charset))
+ (not (mm-coding-system-equal
+ buffer-file-coding-system mule-charset)))
+ (mm-decode-coding-region (point-min) (point-max) mule-charset))))))
+
+(provide 'mm-bodies)
+
+;; mm-bodies.el ends here
(fset 'mm-encode-coding-string (lambda (s a) s))))
(eval-and-compile
+ (if (fboundp 'encode-coding-region)
+ (fset 'mm-encode-coding-region 'encode-coding-region)
+ (fset 'mm-encode-coding-string 'ignore)))
+
+(eval-and-compile
+ (if (fboundp 'decode-coding-region)
+ (fset 'mm-decode-coding-region 'decode-coding-region)
+ (fset 'mm-decode-coding-string 'ignore)))
+
+(eval-and-compile
(if (fboundp 'coding-system-list)
(fset 'mm-coding-system-list 'coding-system-list)
(fset 'mm-coding-system-list 'ignore)))
+(eval-and-compile
+ (if (fboundp 'coding-system-equal)
+ (fset 'mm-coding-system-equal 'coding-system-equal)
+ (fset 'mm-coding-system-equal 'equal)))
+
(defvar mm-mime-mule-charset-alist
'((us-ascii ascii)
(iso-8859-1 latin-iso8859-1)
(setq idx (1+ idx)))
string))
+(defun mm-enable-multibyte ()
+ "Enable multibyte in the current buffer."
+ (when (fboundp 'set-buffer-multibyte)
+ (set-buffer-multibyte t)))
+
+(defun mm-insert-rfc822-headers (charset encoding)
+ "Insert text/plain headers with CHARSET and ENCODING."
+ (insert "MIME-Version: 1.0\n")
+ (insert "Content-Type: text/plain; charset=\""
+ (downcase (symbol-name charset)) "\"\n")
+ (insert "Content-Transfer-Encoding: "
+ (downcase (symbol-name encoding)) "\n"))
+
+(defun mm-content-type-charset (header)
+ "Return the charset parameter from HEADER."
+ (when (string-match "charset *= *\"? *\\([-0-9a-zA-Z_]+\\)\"? *$" header)
+ (intern (downcase (match-string 1 header)))))
+
+(defun mm-read-coding-system (prompt)
+ "Prompt the user for a coding system."
+ (completing-read
+ prompt (mapcar (lambda (s) (list (symbol-name (car s))))
+ mm-mime-mule-charset-alist)))
+
(provide 'mm-util)
;;; mm-util.el ends here
(unless (gnus-buffer-live-p nntp-server-buffer)
(setq nntp-server-buffer (get-buffer-create " *nntpd*")))
(set-buffer nntp-server-buffer)
- (buffer-disable-undo (current-buffer))
(erase-buffer)
(kill-all-local-variables)
(setq case-fold-search t) ;Should ignore case.
:group 'nnmail-split
:type '(repeat (cons :format "%v" symbol regexp)))
-(defcustom nnmail-delete-incoming t
+(defcustom nnmail-delete-incoming nil
"*If non-nil, the mail backends will delete incoming files after
splitting."
:group 'nnmail-retrieve
(downcase (symbol-name encoding)) "?")))
(save-restriction
(narrow-to-region b e)
- (insert
- (prog1
- (mm-encode-coding-string (buffer-string) mime-charset)
- (delete-region (point-min) (point-max))))
+ (mm-encode-coding-region b e mime-charset)
(funcall (cdr (assq encoding rfc2047-encoding-function-alist))
(point-min) (point-max))
(goto-char (point-min))
(defun rfc2047-decode-string (string)
"Decode the quoted-printable-encoded STRING and return the results."
(with-temp-buffer
+ (mm-enable-multibyte)
(insert string)
(inline
(rfc2047-decode-region (point-min) (point-max)))
word)))
(defun rfc2047-decode (charset encoding string)
- "Decode STRING as an encoded text.
+ "Decode STRING that uses CHARSET with ENCODING.
Valid ENCODINGs are \"B\" and \"Q\".
If your Emacs implementation can't decode CHARSET, it returns nil."
(let ((cs (mm-charset-to-coding-system charset)))
1998-08-31 11:46:57 Lars Magne Ingebrigtsen <larsi@gnus.org>
* gnus.texi (Mail Folders): Addition.
+ (Group Parameters): Addition.
+ (MIME Commands): New.
1998-08-27 07:29:17 Lars Magne Ingebrigtsen <larsi@gnus.org>
\input texinfo @c -*-texinfo-*-
@setfilename gnus
-@settitle Pterodactyl Gnus 0.10 Manual
+@settitle Pterodactyl Gnus 0.13 Manual
@synindex fn cp
@synindex vr cp
@synindex pg cp
@tex
@titlepage
-@title Pterodactyl Gnus 0.10 Manual
+@title Pterodactyl Gnus 0.13 Manual
@author by Lars Magne Ingebrigtsen
@page
spool or your mbox file. All at the same time, if you want to push your
luck.
-This manual corresponds to Pterodactyl Gnus 0.10.
+This manual corresponds to Pterodactyl Gnus 0.13.
@end ifinfo
Gnus, but provide a place for you to store information on particular
groups.
+@item charset
+Elements that look like @code{(charset . iso-8859-1)} will make
+@code{iso-8859-1} the default charset; that is, the charset that will be
+used for all articles that do not specify a charset.
+
@item @var{(variable form)}
You can use the group parameters to set variables local to the group you
are entering. If you want to turn threading off in @samp{news.answers},
* Saving Articles:: Ways of customizing article saving.
* Decoding Articles:: Gnus can treat series of (uu)encoded articles.
* Article Treatment:: The article buffer can be mangled at will.
+* MIME Commands:: Doing MIMEy things with the articles.
* Article Commands:: Doing various things with the article buffer.
* Summary Sorting:: Sorting the summary buffer in various ways.
* Finding the Parent:: No child support? Get the parent.
signature after all.
+@node MIME Commands
+@section MIME Commands
+@cindex MIME decoding
+
+@table @kbd
+@item W M w
+@kindex W M w (Summary)
+Decode RFC2047-encoded words in the article headers
+(@code{gnus-article-decode-mime-words}).
+
+@item W M c
+@kindex W M c (Summary)
+Decode encoded article bodies as well as charsets
+(@code{gnus-article-decode-charset}).
+
+This command looks in the @code{Content-Type} header to determine the
+charset. If there is no such header in the article, you can give it a
+prefix, which will prompt for the charset to decode as. In regional
+groups where people post using some common encoding (but do not include
+MIME headers), you can set the @code{charset} group/topic parameter to
+the required charset (@pxref{Group Parameters}).
+
+@end table
+
+
@node Article Commands
@section Article Commands
@item summary-highlight
Do highlights in the summary buffer.
@item article-highlight
-Do highlights in the article buffer.
+Do highlights according to @code{gnus-article-display-hook} in the
+article buffer.
@item highlight
Turn on highlighting in all buffers.
@item group-menu
\input texinfo @c -*-texinfo-*-
@setfilename message
-@settitle Pterodactyl Message 0.10 Manual
+@settitle Pterodactyl Message 0.13 Manual
@synindex fn cp
@synindex vr cp
@synindex pg cp
@tex
@titlepage
-@title Pterodactyl Message 0.10 Manual
+@title Pterodactyl Message 0.13 Manual
@author by Lars Magne Ingebrigtsen
@page
* Key Index:: List of Message mode keys.
@end menu
-This manual corresponds to Pterodactyl Message 0.10. Message is
+This manual corresponds to Pterodactyl Message 0.13. Message is
distributed with the Gnus distribution bearing the same version number
as this manual has.