\f
* Changes in Oort Gnus
+** Support for non-ASCII domain names
+
+Message supports non-ASCII domain names in From:, To: and Cc: and will
+query you whether to perform encoding when you try to send a message.
+The variable `message-use-idna' controls this. Gnus will also decode
+non-ASCII domain names in From:, To: and Cc: when you view a message.
+The variable `gnus-use-idna' controls this.
+
** Better handling of Microsoft citation styles
Gnus now tries to recognize the mangled header block that some Microsoft
+2003-03-19 Simon Josefsson <jas@extundo.com>
+
+ * gnus-idna.el: Update.
+
2003-03-11 Teodor Zlatanov <tzz@lifelogs.com>
* hashcash.el (hashcash-version, hashcash-insert-payment): patch
;;; Commentary:
-;; This package implement crude support for internationalized
-;; (non-ASCII) domain names in Gnus. It is meant as a proof of
-;; concept.
+;; This package implement crude support for internationalized domain
+;; names in Gnus.
;; Theory of Operation:
;; using IDNA ToASCII() when you send mail using Message. The hook
;; used is message-send-hook.
;;
-;; For incoming articles, when QP in headers are decoded, it searches
-;; for "xn--" prefixes and decode them using IDNA ToUnicode(). The
-;; hook used is gnus-article-decode-hook.
+;; For incoming articles, when QP in headers are decoded (i.e., when
+;; gnus-article-decode-hook is invoked), it searches for "xn--"
+;; prefixes and decode them if they are found inside (heuristically
+;; determined) RHS in From:, To: and Cc:, using IDNA ToUnicode().
;; Usage:
-;; Simply put (require 'gnus-idna) in your ~/.gnus or ~/.emacs and it
-;; should work. You need to install GNU Libidn (0.1.11 or later) and
-;; make sure the idna.el installed by it is found by emacs.
+;; You need to install GNU Libidn (0.1.11 or later) and make sure the
+;; idna.el installed by it is found by emacs.
+
+;; If you use an older Gnus, you may need to put the following in your
+;; init scripts too, but keep in mind that most older Gnuses either
+;; doesn't have these hooks or are buggy in other regards so it
+;; doesn't work anyway. (The window of Gnus versions that this works
+;; on is a few weeks during the Oort CVS in winter 2003.) Update to a
+;; recent Gnus instead, then you don't have to do anything.
+
+;; (add-hook 'message-send-hook 'message-idna-to-ascii-rhs)
+;; (add-hook 'gnus-article-decode-hook 'gnus-idna-to-unicode-rhs 'append)
+
+;; Revision history:
+
+;; 2003-02-26 Initial release
+;;
+;; 2003-03-19 Cleanup. Fixes a bug that may corrupt outgoing mail if
+;; it contains From:, To: or Cc: headers in the body.
;;; Code:
(require 'gnus)
+(require 'gnus-util)
(require 'rfc822)
-(require 'idna)
-
-(eval-and-compile
- (cond
- ((fboundp 'replace-in-string)
- (defalias 'gnus-replace-in-string 'replace-in-string))
- ((fboundp 'replace-regexp-in-string)
- (defun gnus-replace-in-string (string regexp newtext &optional literal)
- (replace-regexp-in-string regexp newtext string nil literal)))
- (t
- (defun gnus-replace-in-string (string regexp newtext &optional literal)
- (let ((start 0) tail)
- (while (string-match regexp string start)
- (setq tail (- (length string) (match-end 0)))
- (setq string (replace-match newtext nil literal string))
- (setq start (- (length string) tail))))
- string))))
-
-(defun gnus-idna-to-ascii-rhs-1 (header)
- (save-excursion
- (save-restriction
- (let (address header-data new-header-data rhs ace)
+(autoload 'idna-to-ascii "idna")
+(autoload 'idna-to-unicode "idna")
+
+(defcustom message-use-idna 'ask
+ "Whether to encode non-ASCII in domain names into ASCII according to IDNA."
+ :type '(choice (const :tag "Ask" ask)
+ (const :tag "Never" nil)
+ (const :tag "Always" t)))
+
+(defun message-idna-inside-rhs-p ()
+ "Return t iff point is inside a RHS (heuristically).
+Only works properly if header contains mailbox-list or address-list.
+I.e., calling it on a Subject: header is useless."
+ (if (re-search-backward
+ "[\\\n\r\t ]" (save-excursion (search-backward "@" nil t)) t)
+ ;; whitespace between @ and point
+ nil
+ (let ((dquote 1) (paren 1))
+ (while (save-excursion (re-search-backward "[^\\]\"" nil t dquote))
+ (incf dquote))
+ (while (save-excursion (re-search-backward "[^\\]\(" nil t paren))
+ (incf paren))
+ (and (= (% dquote 2) 1) (= (% paren 2) 1)))))
+
+(defun message-idna-to-ascii-rhs-1 (header)
+ "Interactively potentially IDNA encode domain names in HEADER."
+ (let (rhs ace start end startpos endpos)
+ (goto-char (point-min))
+ (setq start (re-search-forward (concat "^" header) nil t)
+ end (or (save-excursion (re-search-forward "^[ \t]" nil t))
+ (point-max)))
+ (when (and start end)
+ (while (re-search-forward "@\\([^ \t\r\n>]+\\)" end t)
+ (setq rhs (match-string-no-properties 1)
+ startpos (match-beginning 1)
+ endpos (match-end 1))
+ (when (save-match-data
+ (and (message-idna-inside-rhs-p)
+ (setq ace (idna-to-ascii rhs))
+ (not (string= rhs ace))
+ (if (eq message-use-idna 'ask)
+ (unwind-protect
+ (progn
+ (replace-highlight startpos endpos)
+ (y-or-n-p
+ (format "Replace with `%s'? " ace)))
+ (message "")
+ (replace-dehighlight))
+ message-use-idna)))
+ (replace-match (concat "@" ace)))))))
+
+;;;###autoload
+(defun message-idna-to-ascii-rhs ()
+ "Possibly IDNA encode non-ASCII domain names in From:, To: and Cc: headers.
+See `message-idna-encode'."
+ (interactive)
+ (when (condition-case nil (require 'idna) (file-error))
+ (save-excursion
+ (save-restriction
(message-narrow-to-head)
- (setq header-data (message-fetch-field header))
- (when header-data
- (dolist (element (message-tokenize-header header-data))
- (setq address (car (rfc822-addresses element)))
- (when (string-match "\\(.*\\)@\\([^@]+\\)" address)
- (setq ace (if (setq rhs (match-string 2 address))
- (idna-to-ascii rhs)))
- (push (if (string= rhs ace)
- element
- (gnus-replace-in-string
- element (regexp-quote rhs) ace t))
- new-header-data)))
- (message-remove-header header)
- (message-position-on-field header)
- (dolist (addr (reverse new-header-data))
- (insert addr ", "))
- (when new-header-data
- (delete-backward-char 2)))))))
-
-(defun gnus-idna-to-ascii-rhs ()
- (gnus-idna-to-ascii-rhs-1 "From")
- (gnus-idna-to-ascii-rhs-1 "To")
- (gnus-idna-to-ascii-rhs-1 "Cc"))
-
-(add-hook 'message-send-hook 'gnus-idna-to-ascii-rhs)
+ (message-idna-to-ascii-rhs-1 "From")
+ (message-idna-to-ascii-rhs-1 "To")
+ (message-idna-to-ascii-rhs-1 "Cc")))))
+;;;###autoload
(defun gnus-idna-to-unicode-rhs ()
- (let ((inhibit-point-motion-hooks t)
- buffer-read-only)
- (goto-char (point-min))
- (while (re-search-forward "xn--.*[ \t\n\r.,<>()@!]" nil t)
- ;(or (eobp) (forward-char))
- (let (ace unicode)
- (when (setq ace (match-string 0))
- (setq unicode (idna-to-unicode ace))
- (unless (string= ace unicode)
- (replace-match unicode)))))))
-
-(add-hook 'gnus-article-decode-hook 'gnus-idna-to-unicode-rhs 'append)
+ "Decode IDNA strings in RHS in From:, To: and Cc: headers in current buffer."
+ (when (condition-case nil (require 'idna) (file-error))
+ (let ((inhibit-point-motion-hooks t)
+ buffer-read-only)
+ (article-narrow-to-head)
+ (goto-char (point-min))
+ (while (re-search-forward "\\(xn--.*\\)[ \t\n\r,>]" nil t)
+ (let (ace unicode)
+ (when (save-match-data
+ (and (setq ace (match-string 1))
+ (save-excursion (and (re-search-backward "^[^ \t]" nil t)
+ (looking-at "From\\|To\\|Cc")))
+ (save-excursion (backward-char)
+ (message-idna-inside-rhs-p))
+ (setq unicode (idna-to-unicode ace))))
+ (unless (string= ace unicode)
+ (replace-match unicode nil nil nil 1))))))))
(provide 'gnus-idna)
+2003-03-20 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * gnus-cache.el (gnus-cache-braid-nov): Test if a line looks like
+ a NOV.
+
+2003-03-20 Simon Josefsson <jas@extundo.com>
+
+ * message.el (message-use-idna): Disable if UTF-8 unavailable.
+ (message-idna-to-ascii-rhs): Use it.
+
+ * gnus-art.el (gnus-use-idna): Disable if UTF-8 unavailable.
+
+2003-03-19 Teodor Zlatanov <tzz@lifelogs.com>
+
+ * spam.el (spam-group-ham-mark-p, spam-group-spam-mark-p)
+ (spam-group-ham-marks, spam-group-spam-marks): new functions
+ (spam-spam-marks, spam-ham-marks): removed in favor of the
+ spam-marks and ham-marks parameters
+ (spam-generic-register-routine, spam-ham-move-routine): use the
+ new spam-group-{spam,ham}-mark-p functions
+
+ * gnus.el (spam-marks, ham-marks): new group parameters with
+ default values same as the old spam-spam-marks and spam-ham-marks
+
+2003-03-19 Simon Josefsson <jas@extundo.com>
+
+ * gnus-art.el (gnus-article-decode-hook): Add IDNA.
+ (gnus-use-idna): New variable.
+ (article-decode-idna-rhs): New function.
+
+ * message.el (message-use-idna): New variable.
+ (message-mode-field-menu): Add entry for IDNA.
+ (message-idna-inside-rhs-p, message-idna-to-ascii-rhs-1)
+ (message-idna-to-ascii-rhs): New function.
+ (message-generate-headers): Invoke IDNA code.
+
+2003-03-19 Paul Jarc <prj@po.cwru.edu>
+
+ * nnmaildir.el (nnmaildir--system-name): New function.
+ (nnmaildir-request-accept-article): Use it.
+
+2003-03-19 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * gnus-util.el (gnus-byte-compile): Make it work silently as the
+ gnus-compile function does.
+
+ * gnus-sum.el (gnus-summary-highlight-line-0): Revoke the last
+ bogus change.
+
2003-03-19 Jesper Harder <harder@ifa.au.dk>
* mm-util.el (mm-mule-charset-to-mime-charset): Test if
(item :tag "skip" nil)
(face :value default)))))
-(defcustom gnus-article-decode-hook nil
+(defcustom gnus-article-decode-hook
+ '(article-decode-group-name article-decode-idna-rhs)
"*Hook run to decode charsets in articles."
:group 'gnus-article-headers
:type 'hook)
(defvar gnus-article-wash-function nil
"Function used for converting HTML into text.")
+(defcustom gnus-use-idna (and (condition-case nil (require 'idna) (file-error))
+ (fboundp 'coding-system-p)
+ (coding-system-p 'utf-8))
+ "Whether IDNA decoding of headers is used when viewing messages.
+This requires GNU Libidn, and by default only enabled if it is found."
+ :group 'gnus-article-headers
+ :type 'boolean)
+
;;; Internal variables
(defvar gnus-english-month-names
(nnmail-fetch-field "Followup-To"))
gnus-newsgroup-name method))))))
+(autoload 'idna-to-unicode "idna")
+
+(defun article-decode-idna-rhs ()
+ "Decode IDNA strings in RHS in From:, To: and Cc: headers in current buffer."
+ (when gnus-use-idna
+ (save-restriction
+ (let ((inhibit-point-motion-hooks t)
+ buffer-read-only)
+ (article-narrow-to-head)
+ (goto-char (point-min))
+ (while (re-search-forward "\\(xn--.*\\)[ \t\n\r,>]" nil t)
+ (let (ace unicode)
+ (when (save-match-data
+ (and (setq ace (match-string 1))
+ (save-excursion
+ (and (re-search-backward "^[^ \t]" nil t)
+ (looking-at "From\\|To\\|Cc")))
+ (save-excursion (backward-char)
+ (message-idna-inside-rhs-p))
+ (setq unicode (idna-to-unicode ace))))
+ (unless (string= ace unicode)
+ (replace-match unicode nil nil nil 1)))))))))
+
(defun article-de-quoted-unreadable (&optional force read-charset)
"Translate a quoted-printable-encoded article.
If FORCE, decode the article whether it is marked as quoted-printable
(goto-char (point-min))
(while cached
(while (and (not (eobp))
+ (looking-at "[0-9]+\t")
(< (read (current-buffer)) (car cached)))
(forward-line 1))
(beginning-of-line)
(setcdr c (cons (list (caar list) (list 'quote (cdar list))) nil))
(setq c (cdr c)
list (cdr list)))
- (let ((byte-compile-warnings
- ;; Since XEmacs version of bytecomp complains about
- ;; the unbound variables because of `globally-boundp'
- ;; even if they are bound by `let', we silence it.
- (if (and (boundp 'byte-compile-default-warnings) ;; XEmacs
- (listp (symbol-value
- 'byte-compile-default-warnings)))
- (delq 'free-vars
- (copy-sequence (symbol-value
- 'byte-compile-default-warnings)))
- byte-compile-warnings)))
- (gnus-byte-compile (list 'lambda nil cond)))))))
+ (gnus-byte-compile (list 'lambda nil cond))))))
(defun gnus-summary-highlight-line ()
"Highlight current line according to `gnus-summary-highlight'."
(require 'byte-optimize)
(error))
(require 'bytecomp)
- (defalias 'gnus-byte-compile 'byte-compile)
- (byte-compile form))
+ (defalias 'gnus-byte-compile
+ (lambda (form)
+ (let ((byte-compile-warnings '(unresolved callargs redefine)))
+ (byte-compile form))))
+ (gnus-byte-compile form))
form))
(defun gnus-remassoc (key alist)
(string :tag "Move to a group")
(const :tag "Expire" nil))))
:parameter-document
- "Where ham articles will go at summary exit from a spam group."))
+ "Where ham articles will go at summary exit from a spam group.")
+
+ (gnus-define-group-parameter
+ ham-marks
+ :type 'list
+ :parameter-type '(list :tag "Ham mark choices"
+ (set
+ (variable-item gnus-del-mark)
+ (variable-item gnus-read-mark)
+ (variable-item gnus-killed-mark)
+ (variable-item gnus-kill-file-mark)
+ (variable-item gnus-low-score-mark)))
+
+ :parameter-document
+ "Marks considered ham (positively not spam). Such articles will be
+processed as ham (non-spam) on group exit. When nil, the global
+spam-ham-marks variable takes precedence."
+ :variable-default '((".*" ((gnus-del-mark
+ gnus-read-mark
+ gnus-killed-mark
+ gnus-kill-file-mark
+ gnus-low-score-mark))))
+ :variable-group spam
+ :variable-document
+ "*Groups in which to explicitly set the ham marks to some value.")
+
+ (gnus-define-group-parameter
+ spam-marks
+ :type 'list
+ :parameter-type '(list :tag "Spam mark choices"
+ (set
+ (variable-item gnus-spam-mark)
+ (variable-item gnus-killed-mark)
+ (variable-item gnus-kill-file-mark)
+ (variable-item gnus-low-score-mark)))
+
+ :parameter-document
+ "Marks considered spam.
+Such articles will be processed as spam on group exit. When nil, the global
+spam-spam-marks variable takes precedence."
+ :variable-default '((".*" ((gnus-spam-mark))))
+ :variable-group spam
+ :variable-document
+ "*Groups in which to explicitly set the spam marks to some value."))
(defcustom gnus-group-uncollapsed-levels 1
"Number of group name elements to leave alone when making a short group name."
:link '(custom-manual "(message)News Headers")
:type 'string)
+(defcustom message-use-idna (and (condition-case nil (require 'idna)
+ (file-error))
+ (fboundp 'coding-system-p)
+ (coding-system-p 'utf-8)
+ 'ask)
+ "Whether to encode non-ASCII in domain names into ASCII according to IDNA."
+ :group 'message-headers
+ :type '(choice (const :tag "Ask" ask)
+ (const :tag "Never" nil)
+ (const :tag "Always" t)))
+
;;; Internal variables.
(defvar message-sending-message "Sending...")
["Reduce To: to Cc:" message-reduce-to-to-cc t]
"----"
["Sort Headers" message-sort-headers t]
+ ["Encode non-ASCII domain names" message-idna-to-ascii-rhs t]
["Goto Body" message-goto-body t]
["Goto Signature" message-goto-signature t]))
(concat message-user-agent " " user-agent))
message-user-agent)))))
+(defun message-idna-inside-rhs-p ()
+ "Return t iff point is inside a RHS (heuristically).
+Only works properly if header contains mailbox-list or address-list.
+I.e., calling it on a Subject: header is useless."
+ (if (re-search-backward
+ "[\\\n\r\t ]" (save-excursion (search-backward "@" nil t)) t)
+ ;; whitespace between @ and point
+ nil
+ (let ((dquote 1) (paren 1))
+ (while (save-excursion (re-search-backward "[^\\]\"" nil t dquote))
+ (incf dquote))
+ (while (save-excursion (re-search-backward "[^\\]\(" nil t paren))
+ (incf paren))
+ (and (= (% dquote 2) 1) (= (% paren 2) 1)))))
+
+(autoload 'idna-to-ascii "idna")
+
+(defun message-idna-to-ascii-rhs-1 (header)
+ "Interactively potentially IDNA encode domain names in HEADER."
+ (let (rhs ace start end startpos endpos)
+ (goto-char (point-min))
+ (setq start (re-search-forward (concat "^" header) nil t)
+ end (or (save-excursion (re-search-forward "^[ \t]" nil t))
+ (point-max)))
+ (when (and start end)
+ (while (re-search-forward "@\\([^ \t\r\n>]+\\)" end t)
+ (setq rhs (match-string-no-properties 1)
+ startpos (match-beginning 1)
+ endpos (match-end 1))
+ (when (save-match-data
+ (and (message-idna-inside-rhs-p)
+ (setq ace (idna-to-ascii rhs))
+ (not (string= rhs ace))
+ (if (eq message-use-idna 'ask)
+ (unwind-protect
+ (progn
+ (replace-highlight startpos endpos)
+ (y-or-n-p
+ (format "Replace with `%s'? " ace)))
+ (message "")
+ (replace-dehighlight))
+ message-use-idna)))
+ (replace-match (concat "@" ace)))))))
+
+(defun message-idna-to-ascii-rhs ()
+ "Possibly IDNA encode non-ASCII domain names in From:, To: and Cc: headers.
+See `message-idna-encode'."
+ (interactive)
+ (when message-use-idna
+ (save-excursion
+ (save-restriction
+ (message-narrow-to-head)
+ (message-idna-to-ascii-rhs-1 "From")
+ (message-idna-to-ascii-rhs-1 "To")
+ (message-idna-to-ascii-rhs-1 "Cc")))))
+
(defun message-generate-headers (headers)
"Prepare article HEADERS.
Headers already prepared in the buffer are not modified."
(beginning-of-line))
(when (or (message-news-p)
(string-match "@.+\\.." secure-sender))
- (insert "Sender: " secure-sender "\n")))))))
+ (insert "Sender: " secure-sender "\n"))))
+ ;; Check for IDNA
+ (message-idna-to-ascii-rhs))))
(defun message-insert-courtesy-copy ()
"Insert a courtesy message in mail copies of combined messages."
(defun nnmaildir--up2-1 (n)
(if (zerop n) 1 (1- (lsh 1 (1+ (logb n))))))
+(defun nnmaildir--system-name ()
+ (gnus-replace-in-string
+ (gnus-replace-in-string
+ (gnus-replace-in-string
+ (system-name)
+ "\\\\" "\\134" 'literal)
+ "/" "\\057" 'literal)
+ ":" "\\072" 'literal))
+
(defun nnmaildir-request-type (group &optional article)
'mail)
(setq file (concat file "M" (number-to-string (caddr time)))))
(setq file (concat file nnmaildir--delivery-pid)
file (concat file "Q" (number-to-string nnmaildir--delivery-count))
- file (concat file "." (system-name)) ;;;; FIXME: encode / and :
+ file (concat file "." (nnmaildir--system-name))
tmpfile (concat (nnmaildir--tmp dir) file)
curfile (concat (nnmaildir--cur dir) file ":2,"))
(when (file-exists-p tmpfile)
:type 'regexp
:group 'spam)
-(defcustom spam-ham-marks (list 'gnus-del-mark 'gnus-read-mark
- 'gnus-killed-mark 'gnus-kill-file-mark
- 'gnus-low-score-mark)
- "Marks considered as being ham (positively not spam).
-Such articles will be processed as ham (non-spam) on group exit."
- :type '(set
- (variable-item gnus-del-mark)
- (variable-item gnus-read-mark)
- (variable-item gnus-killed-mark)
- (variable-item gnus-kill-file-mark)
- (variable-item gnus-low-score-mark))
- :group 'spam)
-
-(defcustom spam-spam-marks (list 'gnus-spam-mark)
- "Marks considered as being spam (positively spam).
-Such articles will be transmitted to `bogofilter -s' on group exit."
- :type '(set
- (variable-item gnus-spam-mark)
- (variable-item gnus-killed-mark)
- (variable-item gnus-kill-file-mark)
- (variable-item gnus-low-score-mark))
- :group 'spam)
-
(defcustom spam-face 'gnus-splash-face
"Face for spam-marked articles"
:type 'face
gnus-summary-highlight)
;; convenience functions
+(defun spam-group-ham-mark-p (group mark &optional spam)
+ (when (stringp group)
+ (let* ((marks (spam-group-ham-marks group spam))
+ (marks (if (symbolp mark)
+ marks
+ (mapcar 'symbol-value marks))))
+ (memq mark marks))))
+
+(defun spam-group-spam-mark-p (group mark)
+ (spam-group-ham-mark-p group mark t))
+
+(defun spam-group-ham-marks (group &optional spam)
+ (when (stringp group)
+ (let* ((marks (if spam
+ (gnus-parameter-spam-marks group)
+ (gnus-parameter-ham-marks group)))
+ (marks (car marks))
+ (marks (if (listp (car marks)) (car marks) marks)))
+ marks)))
+
+(defun spam-group-spam-marks (group)
+ (spam-group-ham-marks group t))
+
(defun spam-group-spam-contents-p (group)
(if (stringp group)
(or (member group spam-junk-mailgroups)
(defun spam-ham-move-routine (&optional group copy)
(gnus-summary-kill-process-mark)
(let ((articles gnus-newsgroup-articles)
- article ham-mark-values mark tomove)
+ article mark tomove)
(when (stringp group) ; this routine will do nothing
; without a valid group
- (dolist (mark spam-ham-marks)
- (push (symbol-value mark) ham-mark-values))
(dolist (article articles)
- (when (memq (gnus-summary-article-mark article) ham-mark-values)
+ (when (spam-group-spam-mark-p gnus-newsgroup-name
+ (gnus-summary-article-mark article))
(push article tomove)))
;; now do the actual move
(defun spam-generic-register-routine (spam-func ham-func)
(let ((articles gnus-newsgroup-articles)
- article mark ham-articles spam-articles spam-mark-values
- ham-mark-values)
-
- ;; marks are stored as symbolic values, so we have to dereference
- ;; them for memq to work. we wouldn't have to do this if
- ;; gnus-summary-article-mark returned a symbol.
- (dolist (mark spam-ham-marks)
- (push (symbol-value mark) ham-mark-values))
-
- (dolist (mark spam-spam-marks)
- (push (symbol-value mark) spam-mark-values))
+ article mark ham-articles spam-articles)
(while articles
(setq article (pop articles)
mark (gnus-summary-article-mark article))
- (cond ((memq mark spam-mark-values) (push article spam-articles))
+ (cond ((spam-group-spam-mark-p gnus-newsgroup-name mark)
+ (push article spam-articles))
((memq article gnus-newsgroup-saved))
- ((memq mark ham-mark-values) (push article ham-articles))))
+ ((spam-group-ham-mark-p gnus-newsgroup-name mark)
+ (push article ham-articles))))
+
(when (and ham-articles ham-func)
(mapc ham-func ham-articles)) ; we use mapc because unlike
; mapcar it discards the
+2003-03-19 Simon Josefsson <jas@extundo.com>
+
+ * gnus.texi (Misc Article): Add.
+ (Agent Basics): Fix makeinfo warnings.
+
+ * message.texi (IDNA): New.
+
2003-03-18 Kevin Greiner <kgreiner@xpediantsolutions.com>
* gnus.texi (Gnus Unplugged): Refer to new agent Group/Topic
@vindex gnus-page-delimiter
\e$B$3$l$,>e$G?($l$?6h@Z$jJ8;z$G$9!#%G%#%U%)%k%H$G$O\e(B @samp{^L} (\e$B%U%)!<%`\e(B
\e$B%U%#!<%I!"2~JG\e(B) \e$B$G$9!#\e(B
+
+@c TRANSLATEME
+@cindex IDNA
+@cindex internationalized domain names
+@vindex gnus-use-idna
+@item gnus-use-idna
+This variable controls whether Gnus performs IDNA decoding of
+internationalized domain names inside @sc{From:}, @sc{To:} and
+@sc{Cc:} headers. This requires GNU Libidn
+(@url{http://www.gnu.org/software/libidn/}, and this variable is only
+enabled if you have installed it.
@end table
@node Composing Messages
parameters to implement your policy. If you're new to gnus, it
is probably best to start with a category @xref{Agent Categories}.
-Both topic parameters (@xref{Topic Parameters}) and agent
-categories (@xref{Agent Categories}) provide for setting a policy that
-applies to multiple groups. Which you use is entirely up to you. Topic
-parameters do override categories so, if you mix the two, you'll have to
-take that into account. If you have a few groups that deviate from your
-policy, you can use @xref{Group Parameters} to configure them.
+Both topic parameters (@pxref{Topic Parameters}) and agent categories
+(@pxref{Agent Categories}) provide for setting a policy that applies
+to multiple groups. Which you use is entirely up to you. Topic
+parameters do override categories so, if you mix the two, you'll have
+to take that into account. If you have a few groups that deviate from
+your policy, you can use grou parameters (@pxref{Group Parameters}) to
+configure them.
@item
\e$B$($($H\e(B@dots{}\e$B!"0J>e$G$9!#\e(B
@vindex gnus-page-delimiter
This is the delimiter mentioned above. By default, it is @samp{^L}
(formfeed).
+
+@cindex IDNA
+@cindex internationalized domain names
+@vindex gnus-use-idna
+@item gnus-use-idna
+This variable controls whether Gnus performs IDNA decoding of
+internationalized domain names inside @sc{From:}, @sc{To:} and
+@sc{Cc:} headers. This requires GNU Libidn
+(@url{http://www.gnu.org/software/libidn/}, and this variable is only
+enabled if you have installed it.
+
@end table
parameters to implement your policy. If you're new to gnus, it
is probably best to start with a category @xref{Agent Categories}.
-Both topic parameters (@xref{Topic Parameters}) and agent
-categories (@xref{Agent Categories}) provide for setting a policy that
-applies to multiple groups. Which you use is entirely up to you. Topic
-parameters do override categories so, if you mix the two, you'll have to
-take that into account. If you have a few groups that deviate from your
-policy, you can use @xref{Group Parameters} to configure them.
+Both topic parameters (@pxref{Topic Parameters}) and agent categories
+(@pxref{Agent Categories}) provide for setting a policy that applies
+to multiple groups. Which you use is entirely up to you. Topic
+parameters do override categories so, if you mix the two, you'll have
+to take that into account. If you have a few groups that deviate from
+your policy, you can use grou parameters (@pxref{Group Parameters}) to
+configure them.
@item
Uhm@dots{} that's it.
* Movement:: Moving around in message buffers.
* Insertion:: Inserting things into message buffers.
* MIME:: @sc{mime} considerations.
+* IDNA:: Non-ASCII domain name considerations.
* Security:: Signing and encrypting messages.
* Various Commands:: Various things.
* Sending:: Actually sending the message.
language (@pxref{Composing, , Composing, emacs-mime, The Emacs MIME
Manual}).
+@node IDNA
+@section IDNA
+@cindex IDNA
+@cindex internationalized domain names
+@cindex non-ascii domain names
+
+Message is a @sc{idna}-compliant posting agent. The user generally
+doesn't have to do anything to make the @sc{idna} happen---Message
+will encode non-ASCII domain names in @code{From}, @code{To}, and
+@code{Cc} headers automatically.
+
+Until IDNA becomes more well known, Message queries you whether IDNA
+encoding of the domain name really should occur. Some users might not
+be aware that domain names can contain non-ASCII now, so this gives
+them a safety net if they accidently typed a non-ASCII domain name.
+
+@vindex message-use-idna
+The @code{message-use-idna} variable control whether @sc{idna} is
+used. If the variable is @sc{nil} no IDNA encoding will ever happen,
+if it is set to the symbol @sc{ask} the user will be queried (the
+default), and if set to @sc{t} IDNA encoding happens automatically.
+
+@findex message-idna-to-ascii-rhs
+If you want to experiment with the IDNA encoding, you can invoke
+@kbd{M-x message-idna-to-ascii-rhs RET} in the message buffer to have
+the non-ASCII domain names encoded while you edit the message.
+
+Note that you must have GNU Libidn
+(@url{http://www.gnu.org/software/libidn/} installed in order to use
+this functionality.
+
@node Security
@section Security
@cindex Security