Really.
[gnus] / lisp / rfc2047.el
index 0492fd1..b045495 100644 (file)
@@ -93,6 +93,9 @@ quoted-printable and base64 respectively.")
     (nil . ignore))
   "Alist of RFC2047 encodings to encoding functions.")
 
+(defvar rfc2047-encode-encoded-words t
+  "Whether encoded words should be encoded again.")
+
 ;;;
 ;;; Functions for encoding RFC2047 messages
 ;;;
@@ -134,7 +137,7 @@ This is either `base64' or `quoted-printable'."
     (save-restriction
       (rfc2047-narrow-to-field)
       (re-search-forward ":[ \t\n]*" nil t)
-      (buffer-substring (point) (point-max)))))
+      (buffer-substring-no-properties (point) (point-max)))))
 
 (defvar rfc2047-encoding-type 'address-mime
   "The type of encoding done by `rfc2047-encode-region'.
@@ -235,8 +238,11 @@ The buffer may be narrowed."
   (require 'message)                   ; for message-posting-charset
   (let ((charsets
         (mm-find-mime-charset-region (point-min) (point-max))))
-    (and charsets
-        (not (equal charsets (list (car message-posting-charset)))))))
+    (goto-char (point-min))
+    (or (and rfc2047-encode-encoded-words
+            (search-forward "=?" nil t))
+       (and charsets
+            (not (equal charsets (list (car message-posting-charset))))))))
 
 ;; Use this syntax table when parsing into regions that may need
 ;; encoding.  Double quotes are string delimiters, backslash is
@@ -284,18 +290,23 @@ Dynamically bind `rfc2047-encoding-type' to change that."
        ;; is relevant for instance in Subject headers with `Re:' for
        ;; interoperability with non-MIME clients, and we might as
        ;; well avoid the tail too.
-       (progn
+       (let ((encodable-regexp
+              (if rfc2047-encode-encoded-words
+                  "[^\000-\177]\\|=\\?"
+                "[^\000-\177]")))
          (goto-char (point-min))
          ;; Does it need encoding?
-         (skip-chars-forward "\000-\177")
+         (re-search-forward encodable-regexp (point-max) 'move)
          (unless (eobp)
            (skip-chars-backward "^ \n") ; beginning of space-delimited word
-           (rfc2047-encode (point) (progn
-                                     (goto-char e)
-                                     (skip-chars-backward "\000-\177")
-                                     (skip-chars-forward "^ \n")
-                                     ;; end of space-delimited word
-                                     (point)))))
+           (rfc2047-encode
+            (point)
+            (progn
+              (goto-char e)
+              (re-search-backward encodable-regexp (point-max) 'move)
+              (skip-chars-forward "^ \n")
+              ;; end of space-delimited word
+              (point)))))
       ;; `address-mime' case -- take care of quoted words, comments.
       (with-syntax-table rfc2047-syntax-table
        (let ((start)                   ; start of current token
@@ -385,7 +396,7 @@ By default, the string is treated as containing addresses (see
   "Encode the word(s) in the region B to E.
 By default, the region is treated as containing addresses (see
 `rfc2047-encoding-type')."
-  (let* ((mime-charset (mm-find-mime-charset-region b e))
+  (let* ((mime-charset (or (mm-find-mime-charset-region b e) (list 'us-ascii)))
         (cs (if (> (length mime-charset) 1)
                 ;; Fixme: Instead of this, try to break region into
                 ;; parts that can be encoded separately.
@@ -406,7 +417,7 @@ By default, the region is treated as containing addresses (see
                           'Q))))
         (start (concat
                 "=?" (downcase (symbol-name mime-charset)) "?"
-                (downcase (symbol-name encoding)) "?"))
+                (upcase (symbol-name encoding)) "?"))
         (factor (case mime-charset
                   ((iso-8859-5 iso-8859-7 iso-8859-8 koi8-r) 1)
                   ((big5 gb2312 euc-kr) 2)
@@ -608,7 +619,7 @@ By default, the region is treated as containing addresses (see
 (eval-and-compile
   (defconst rfc2047-encoded-word-regexp
     "=\\?\\([^][\000-\040()<>@,\;:*\\\"/?.=]+\\)\\(?:\\*[^?]+\\)?\
-\\?\\(B\\|Q\\)\\?\\([!->@-~ +]*\\)\\?="))
+\\?\\(B\\|Q\\)\\?\\([!->@-~ ]*\\)\\?="))
 
 ;; Fixme: This should decode in place, not cons intermediate strings.
 ;; Also check whether it needs to worry about delimiting fields like