Synch to Oort Gnus 200303200032.
authoryamaoka <yamaoka>
Thu, 20 Mar 2003 01:16:57 +0000 (01:16 +0000)
committeryamaoka <yamaoka>
Thu, 20 Mar 2003 01:16:57 +0000 (01:16 +0000)
16 files changed:
GNUS-NEWS
contrib/ChangeLog
contrib/gnus-idna.el
lisp/ChangeLog
lisp/gnus-art.el
lisp/gnus-cache.el
lisp/gnus-sum.el
lisp/gnus-util.el
lisp/gnus.el
lisp/message.el
lisp/nnmaildir.el
lisp/spam.el
texi/ChangeLog
texi/gnus-ja.texi
texi/gnus.texi
texi/message.texi

index b399c7b..8f39bfd 100644 (file)
--- a/GNUS-NEWS
+++ b/GNUS-NEWS
@@ -8,6 +8,14 @@ For older news, see Gnus info node "New Features".
 \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
index 4f6586b..dea7109 100644 (file)
@@ -1,3 +1,7 @@
+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
index 32eb2f8..15c47b6 100644 (file)
@@ -24,9 +24,8 @@
 
 ;;; 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)
 
index 7e1be81..0a9528d 100644 (file)
@@ -1,3 +1,52 @@
+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
index d84e51c..1f76669 100644 (file)
@@ -731,7 +731,8 @@ displayed by the first non-nil matching CONTENT face."
                               (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)
@@ -1418,6 +1419,14 @@ It is a string, such as \"PGP\". If nil, ask user."
 (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
@@ -2255,6 +2264,29 @@ If PROMPT (the prefix), prompt for a coding system to use."
                                    (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
index e9733a2..0194803 100644 (file)
@@ -511,6 +511,7 @@ Returns the list of articles removed."
     (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)
index ad9f6e5..5cc2b95 100644 (file)
@@ -11218,18 +11218,7 @@ If REVERSE, save parts that do not match TYPE."
               (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'."
index df890d1..6f924dc 100644 (file)
@@ -1168,8 +1168,11 @@ Setting it to nil has no effect after first time running
            (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)
index 2030ffb..fc93a9b 100644 (file)
@@ -1983,7 +1983,50 @@ mail groups, and only works in spam groups."
                      (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."
index 7abec7f..2009338 100644 (file)
@@ -1504,6 +1504,17 @@ no, only reply back to the author."
   :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...")
@@ -2413,6 +2424,7 @@ Point is left at the beginning of the narrowed-to region."
    ["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]))
 
@@ -5260,6 +5272,62 @@ string."
              (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."
@@ -5413,7 +5481,9 @@ 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."
index e49b77a..a625bf2 100644 (file)
@@ -547,6 +547,15 @@ by nnmaildir-request-article.")
 (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)
 
@@ -1318,7 +1327,7 @@ by nnmaildir-request-article.")
        (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)
index dc44be1..fc5b8c6 100644 (file)
@@ -187,29 +187,6 @@ All unmarked article in such group receive the spam mark on group entry."
   :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
@@ -313,6 +290,29 @@ your main source of newsgroup names."
       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)
@@ -466,13 +466,12 @@ your main source of newsgroup names."
 (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
@@ -488,24 +487,17 @@ your main source of newsgroup names."
  
 (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
index bfe6ec9..8020268 100644 (file)
@@ -1,3 +1,10 @@
+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
index 91d1f1f..0b23be9 100644 (file)
@@ -10388,6 +10388,17 @@ GNUS \e$B$d\e(B Gnus \e$B$G$O!"$3$N$?$A$N0-$$LdBj$G6C$+$5$l$J$$$h$&$K$9$k$K$O!"35N,
 @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
@@ -16618,12 +16629,13 @@ you are going to use agent categories, topic parameters, and/or group
 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
index fdd35cc..2f1ea2c 100644 (file)
@@ -10941,6 +10941,17 @@ paging will not be done.
 @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
 
 
@@ -17020,12 +17031,13 @@ you are going to use agent categories, topic parameters, and/or group
 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.
index c387174..bbeaaf0 100644 (file)
@@ -503,6 +503,7 @@ better than you do.
 * 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.
@@ -833,6 +834,37 @@ You can also create arbitrarily complex multiparts using the MML
 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