* nnimap.el (nnimap-split-fancy): Ditto.
[gnus] / lisp / mm-util.el
index e64e325..a705b82 100644 (file)
@@ -1,5 +1,6 @@
 ;;; mm-util.el --- Utility functions for Mule and low level things
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+;;   Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>
@@ -40,7 +41,6 @@
      (coding-system-list . ignore)
      (decode-coding-region . ignore)
      (char-int . identity)
-     (device-type . ignore)
      (coding-system-equal . equal)
      (annotationp . ignore)
      (set-buffer-file-coding-system . ignore)
@@ -69,6 +69,7 @@
              (setq idx (1+ idx)))
            string)))
      (string-as-unibyte . identity)
+     (string-make-unibyte . identity)
      (string-as-multibyte . identity)
      (multibyte-string-p . ignore))))
 
        '((iso-8859-15 . iso-8859-1)))
     ;; Windows-1252 is actually a superset of Latin-1.  See also
     ;; `gnus-article-dumbquotes-map'.
-    ,@(unless (mm-coding-system-p 'windows-1252)       
+    ,@(unless (mm-coding-system-p 'windows-1252)
        (if (mm-coding-system-p 'cp1252)
           '((windows-1252 . cp1252))
         '((windows-1252 . iso-8859-1))))
@@ -245,7 +246,7 @@ Valid elements include:
 `iso-2022-jp-2'  convert ISO-2022-jp to ISO-2022-jp-2 if ISO-2022-jp-2 exists."
 )
 
-(defvar mm-iso-8859-15-compatible 
+(defvar mm-iso-8859-15-compatible
   '((iso-8859-1 "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE")
     (iso-8859-9 "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE\xD0\xDD\xDE\xF0\xFD\xFE"))
   "ISO-8859-15 exchangeable coding systems and inconvertible characters.")
@@ -253,37 +254,43 @@ Valid elements include:
 (defvar mm-iso-8859-x-to-15-table
   (and (fboundp 'coding-system-p)
        (mm-coding-system-p 'iso-8859-15)
-       (mapcar 
+       (mapcar
        (lambda (cs)
          (if (mm-coding-system-p (car cs))
-             (let ((c (string-to-char 
+             (let ((c (string-to-char
                        (decode-coding-string "\341" (car cs)))))
                (cons (char-charset c)
                      (cons
-                      (- (string-to-char 
+                      (- (string-to-char
                           (decode-coding-string "\341" 'iso-8859-15)) c)
-                      (string-to-list (decode-coding-string (car (cdr cs)) 
+                      (string-to-list (decode-coding-string (car (cdr cs))
                                                             (car cs))))))
            '(gnus-charset 0)))
        mm-iso-8859-15-compatible))
   "A table of the difference character between ISO-8859-X and ISO-8859-15.")
 
-(defvar mm-coding-system-priorities nil
+(defcustom mm-coding-system-priorities
+  (if (boundp 'current-language-environment)
+      (let ((lang (symbol-value 'current-language-environment)))
+       (cond ((string= lang "Japanese")
+              ;; Japanese users may prefer iso-2022-jp to shift-jis.
+              '(iso-2022-jp iso-2022-jp-2 japanese-shift-jis
+                            iso-latin-1 utf-8)))))
   "Preferred coding systems for encoding outgoing mails.
 
 More than one suitable coding systems may be found for some texts.  By
 default, a coding system with the highest priority is used to encode
 outgoing mails (see `sort-coding-systems').  If this variable is set,
-it overrides the default priority.  For example, Japanese users may
-prefer iso-2022-jp to japanese-shift-jis:
-
-\(setq mm-coding-system-priorities
-  '(iso-2022-jp iso-2022-jp-2 japanese-shift-jis utf-8))
-")
+it overrides the default priority."
+  :type '(repeat (symbol :tag "Coding system"))
+  :group 'mime)
 
 (defvar mm-use-find-coding-systems-region
   (fboundp 'find-coding-systems-region)
-  "Use `find-coding-systems-region' to find proper coding systems.")
+  "Use `find-coding-systems-region' to find proper coding systems.
+
+Setting it to nil is useful on Emacsen supporting Unicode if sending
+mail with multiple parts is preferred to sending a Unicode one.")
 
 ;;; Internal variables:
 
@@ -291,9 +298,12 @@ prefer iso-2022-jp to japanese-shift-jis:
 
 (defun mm-mule-charset-to-mime-charset (charset)
   "Return the MIME charset corresponding to the given Mule CHARSET."
-  (if (fboundp 'find-coding-systems-for-charsets)
+  (if (and (fboundp 'find-coding-systems-for-charsets)
+          (fboundp 'sort-coding-systems))
       (let (mime)
-       (dolist (cs (find-coding-systems-for-charsets (list charset)))
+       (dolist (cs (sort-coding-systems
+                    (copy-sequence
+                     (find-coding-systems-for-charsets (list charset)))))
          (unless mime
            (when cs
              (setq mime (coding-system-get cs 'mime-charset)))))
@@ -358,7 +368,7 @@ used as the line break code type of the coding system."
                             default-enable-multibyte-characters
                             (fboundp 'set-buffer-multibyte))
     "Emacs mule.")
-  
+
   (defvar mm-mule4-p (and mm-emacs-mule
                          (fboundp 'charsetp)
                          (not (charsetp 'eight-bit-control)))
@@ -385,7 +395,7 @@ This is a no-op in XEmacs."
 Only used in Emacs Mule 4."
        (set-buffer-multibyte t))
     (defalias 'mm-enable-multibyte-mule4 'ignore))
-  
+
   (if mm-mule4-p
       (defun mm-disable-multibyte-mule4 ()
        "Disable multibyte in the current buffer.
@@ -454,7 +464,7 @@ If the charset is `composition', return the actual one."
     (mm-mule-charset-to-mime-charset charset)))
 
 (defun mm-delete-duplicates (list)
-  "Simple  substitute for CL `delete-duplicates', testing with `equal'."
+  "Simple substitute for CL `delete-duplicates', testing with `equal'."
   (let (result head)
     (while list
       (setq head (car list))
@@ -478,17 +488,17 @@ If the charset is `composition', return the actual one."
          (goto-char (point-min))
          (skip-chars-forward "\0-\177")
          (while (not (eobp))
-           (cond 
-            ((not (setq item (assq (char-charset (setq c (char-after))) 
+           (cond
+            ((not (setq item (assq (char-charset (setq c (char-after)))
                                    mm-iso-8859-x-to-15-table)))
              (forward-char))
             ((memq c (cdr (cdr item)))
              (setq inconvertible t)
              (forward-char))
             (t
-             (insert-before-markers (prog1 (+ c (car (cdr item))) 
-                                      (delete-char 1))))
-           (skip-chars-forward "\0-\177"))))
+             (insert-before-markers (prog1 (+ c (car (cdr item)))
+                                      (delete-char 1)))))
+           (skip-chars-forward "\0-\177")))
        (not inconvertible))))
 
 (defun mm-sort-coding-systems-predicate (a b)
@@ -507,7 +517,7 @@ charset, and a longer list means no appropriate charset."
             ;; system that has one.
             (let ((systems (find-coding-systems-region b e)))
               (when mm-coding-system-priorities
-                (setq systems 
+                (setq systems
                       (sort systems 'mm-sort-coding-systems-predicate)))
               ;; Fixme: The `mime-charset' (`x-ctext') of `compound-text'
               ;; is not in the IANA list.
@@ -521,12 +531,13 @@ charset, and a longer list means no appropriate charset."
               charsets))
        ;; Otherwise we're not multibyte, XEmacs or a single coding
        ;; system won't cover it.
-       (setq charsets 
+       (setq charsets
              (mm-delete-duplicates
               (mapcar 'mm-mime-charset
                       (delq 'ascii
                             (mm-find-charset-region b e))))))
-    (if (and (memq 'iso-8859-15 charsets)
+    (if (and (> (length charsets) 1)
+            (memq 'iso-8859-15 charsets)
             (memq 'iso-8859-15 hack-charsets)
             (save-excursion (mm-iso-8859-x-to-15-region b e)))
        (mapcar (lambda (x) (setq charsets (delq (car x) charsets)))
@@ -550,8 +561,8 @@ Also bind `default-enable-multibyte-characters' to nil.
 Equivalent to `progn' in XEmacs"
   (let ((multibyte (make-symbol "multibyte"))
        (buffer (make-symbol "buffer")))
-    `(if mm-emacs-mule 
-        (let ((,multibyte enable-multibyte-characters)
+    `(if mm-emacs-mule
+        (let ((,multibyte enable-multibyte-characters)
               (,buffer (current-buffer)))
           (unwind-protect
               (let (default-enable-multibyte-characters)
@@ -570,7 +581,7 @@ Mule4 only."
   (let ((multibyte (make-symbol "multibyte"))
        (buffer (make-symbol "buffer")))
     `(if mm-mule4-p
-        (let ((,multibyte enable-multibyte-characters)
+        (let ((,multibyte enable-multibyte-characters)
               (,buffer (current-buffer)))
           (unwind-protect
               (let (default-enable-multibyte-characters)
@@ -685,7 +696,7 @@ START, END and FILENAME.  START and END are buffer positions
 saying what text to write.
 Optional fourth argument specifies the coding system to use when
 encoding the file.
-If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers."
+If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'."
   (let ((coding-system-for-write
         (or codesys mm-text-coding-system-for-write
             mm-text-coding-system))
@@ -703,7 +714,7 @@ If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers."
                              coding-system inhibit)
 
   "Like `write-region'.
-If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers."
+If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'."
   (let ((coding-system-for-write
         (or coding-system mm-text-coding-system-for-write
             mm-text-coding-system))
@@ -729,7 +740,7 @@ If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers."
 
 (if (fboundp 'detect-coding-region)
     (defun mm-detect-coding-region (start end)
-      "Like 'detect-coding-region' except returning the best one."
+      "Like `detect-coding-region' except returning the best one."
       (let ((coding-systems
             (detect-coding-region (point) (point-max))))
        (or (car-safe coding-systems)
@@ -752,6 +763,45 @@ If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers."
     (let ((cs (mm-detect-coding-region start end)))
       cs)))
 
+(defun mm-guess-mime-charset ()
+  "Guess the default MIME charset from the language environment."
+  (let ((language-info
+        (and (boundp 'current-language-environment)
+             (assoc current-language-environment
+                    language-info-alist)))
+       item)
+    (cond
+     ((null language-info)
+      'iso-8859-1)
+     ((setq item
+           (cadr
+            (or (assq 'coding-priority language-info)
+                (assq 'coding-system language-info))))
+      (if (fboundp 'coding-system-get)
+         (or (coding-system-get item 'mime-charset)
+             item)
+       item))
+     ((setq item (car (last (assq 'charset language-info))))
+      (if (eq item 'ascii)
+         'iso-8859-1
+       (mm-mime-charset item)))
+     (t
+      'iso-8859-1))))
+
+;; It is not a MIME function, but some MIME functions use it.
+(defalias 'mm-make-temp-file
+  (if (fboundp 'make-temp-file)
+      'make-temp-file
+    (lambda (prefix &optional dir-flag)
+      (let ((file (expand-file-name
+                  (make-temp-name prefix)
+                  (if (fboundp 'temp-directory)
+                      (temp-directory)
+                    temporary-file-directory))))
+       (if dir-flag
+           (make-directory file))
+       file))))
+
 (provide 'mm-util)
 
 ;;; mm-util.el ends here