comparison lisp/gnus/mm-util.el @ 56927:55fd4f77387a after-merge-gnus-5_10

Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-523 Merge from emacs--gnus--5.10, gnus--rel--5.10 Patches applied: * miles@gnu.org--gnu-2004/emacs--gnus--5.10--base-0 tag of miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-464 * miles@gnu.org--gnu-2004/emacs--gnus--5.10--patch-1 Import from CVS branch gnus-5_10-branch * miles@gnu.org--gnu-2004/emacs--gnus--5.10--patch-2 Merge from lorentey@elte.hu--2004/emacs--multi-tty--0, emacs--cvs-trunk--0 * miles@gnu.org--gnu-2004/emacs--gnus--5.10--patch-3 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--gnus--5.10--patch-4 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-18 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-19 Remove autoconf-generated files from archive * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-20 Update from CVS
author Miles Bader <miles@gnu.org>
date Sat, 04 Sep 2004 13:13:48 +0000
parents 6b7597ec2d66
children 497f0d2ca551 cce1c0ee76ee
comparison
equal deleted inserted replaced
56926:f8e248e9a717 56927:55fd4f77387a
1 ;;; mm-util.el --- Utility functions for Mule and low level things 1 ;;; mm-util.el --- Utility functions for Mule and low level things
2 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 2 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 ;; Free Software Foundation, Inc.
3 4
4 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 5 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
5 ;; MORIOKA Tomohiko <morioka@jaist.ac.jp> 6 ;; MORIOKA Tomohiko <morioka@jaist.ac.jp>
6 ;; This file is part of GNU Emacs. 7 ;; This file is part of GNU Emacs.
7 8
22 23
23 ;;; Commentary: 24 ;;; Commentary:
24 25
25 ;;; Code: 26 ;;; Code:
26 27
27 (eval-when-compile 28 (eval-when-compile (require 'cl))
28 (require 'cl)
29 (defvar mm-mime-mule-charset-alist))
30 (require 'mail-prsvr) 29 (require 'mail-prsvr)
31 30
32 (eval-and-compile 31 (eval-and-compile
33 (mapcar 32 (mapcar
34 (lambda (elem) 33 (lambda (elem)
40 (encode-coding-string . (lambda (s a) s)) 39 (encode-coding-string . (lambda (s a) s))
41 (encode-coding-region . ignore) 40 (encode-coding-region . ignore)
42 (coding-system-list . ignore) 41 (coding-system-list . ignore)
43 (decode-coding-region . ignore) 42 (decode-coding-region . ignore)
44 (char-int . identity) 43 (char-int . identity)
45 (device-type . ignore)
46 (coding-system-equal . equal) 44 (coding-system-equal . equal)
47 (annotationp . ignore) 45 (annotationp . ignore)
48 (set-buffer-file-coding-system . ignore) 46 (set-buffer-file-coding-system . ignore)
49 (make-char 47 (make-char
50 . (lambda (charset int) 48 . (lambda (charset int)
69 (when (= (aref string idx) from) 67 (when (= (aref string idx) from)
70 (aset string idx to)) 68 (aset string idx to))
71 (setq idx (1+ idx))) 69 (setq idx (1+ idx)))
72 string))) 70 string)))
73 (string-as-unibyte . identity) 71 (string-as-unibyte . identity)
72 (string-make-unibyte . identity)
74 (string-as-multibyte . identity) 73 (string-as-multibyte . identity)
75 (multibyte-string-p . ignore) 74 (multibyte-string-p . ignore)
76 (point-at-bol . line-beginning-position) 75 ;; It is not a MIME function, but some MIME functions use it.
77 (point-at-eol . line-end-position) 76 (make-temp-file . (lambda (prefix &optional dir-flag)
77 (let ((file (expand-file-name
78 (make-temp-name prefix)
79 (if (fboundp 'temp-directory)
80 (temp-directory)
81 temporary-file-directory))))
82 (if dir-flag
83 (make-directory file))
84 file)))
78 (insert-byte . insert-char) 85 (insert-byte . insert-char)
79 (multibyte-char-to-unibyte . identity)))) 86 (multibyte-char-to-unibyte . identity))))
80 87
81 (eval-and-compile 88 (eval-and-compile
82 (defalias 'mm-char-or-char-int-p 89 (defalias 'mm-char-or-char-int-p
83 (cond 90 (cond
84 ((fboundp 'char-or-char-int-p) 'char-or-char-int-p) 91 ((fboundp 'char-or-char-int-p) 'char-or-char-int-p)
85 ((fboundp 'char-valid-p) 'char-valid-p) 92 ((fboundp 'char-valid-p) 'char-valid-p)
86 (t 'identity)))) 93 (t 'identity))))
87 94
95 ;; Fixme: This seems always to be used to read a MIME charset, so it
96 ;; should be re-named and fixed (in Emacs) to offer completion only on
97 ;; proper charset names (base coding systems which have a
98 ;; mime-charset defined). XEmacs doesn't believe in mime-charset;
99 ;; test with
100 ;; `(or (coding-system-get 'iso-8859-1 'mime-charset)
101 ;; (coding-system-get 'iso-8859-1 :mime-charset))'
102 ;; Actually, there should be an `mm-coding-system-mime-charset'.
88 (eval-and-compile 103 (eval-and-compile
89 (defalias 'mm-read-coding-system 104 (defalias 'mm-read-coding-system
90 (cond 105 (cond
91 ((fboundp 'read-coding-system) 106 ((fboundp 'read-coding-system)
92 (if (and (featurep 'xemacs) 107 (if (and (featurep 'xemacs)
104 (defun mm-get-coding-system-list () 119 (defun mm-get-coding-system-list ()
105 "Get the coding system list." 120 "Get the coding system list."
106 (or mm-coding-system-list 121 (or mm-coding-system-list
107 (setq mm-coding-system-list (mm-coding-system-list)))) 122 (setq mm-coding-system-list (mm-coding-system-list))))
108 123
109 (defun mm-coding-system-p (sym) 124 (defun mm-coding-system-p (cs)
110 "Return non-nil if SYM is a coding system." 125 "Return non-nil if CS is a symbol naming a coding system.
111 (or (and (fboundp 'coding-system-p) (coding-system-p sym)) 126 In XEmacs, also return non-nil if CS is a coding system object."
112 (memq sym (mm-get-coding-system-list)))) 127 (if (fboundp 'find-coding-system)
128 (find-coding-system cs)
129 (if (fboundp 'coding-system-p)
130 (coding-system-p cs)
131 ;; Is this branch ever actually useful?
132 (memq cs (mm-get-coding-system-list)))))
113 133
114 (defvar mm-charset-synonym-alist 134 (defvar mm-charset-synonym-alist
115 `( 135 `(
116 ;; Perfectly fine? A valid MIME name, anyhow. 136 ;; Perfectly fine? A valid MIME name, anyhow.
117 ,@(unless (mm-coding-system-p 'big5) 137 ,@(unless (mm-coding-system-p 'big5)
120 ,@(unless (mm-coding-system-p 'x-ctext) 140 ,@(unless (mm-coding-system-p 'x-ctext)
121 '((x-ctext . ctext))) 141 '((x-ctext . ctext)))
122 ;; Apparently not defined in Emacs 20, but is a valid MIME name. 142 ;; Apparently not defined in Emacs 20, but is a valid MIME name.
123 ,@(unless (mm-coding-system-p 'gb2312) 143 ,@(unless (mm-coding-system-p 'gb2312)
124 '((gb2312 . cn-gb-2312))) 144 '((gb2312 . cn-gb-2312)))
125 ;; ISO-8859-15 is very similar to ISO-8859-1. 145 ;; ISO-8859-15 is very similar to ISO-8859-1. But it's _different_!
126 ;; But this is just wrong. --fx 146 ,@(unless (mm-coding-system-p 'iso-8859-15)
127 ,@(unless (mm-coding-system-p 'iso-8859-15) ; Emacs 21 defines it.
128 '((iso-8859-15 . iso-8859-1))) 147 '((iso-8859-15 . iso-8859-1)))
148 ;; BIG-5HKSCS is similar to, but different than, BIG-5.
149 ,@(unless (mm-coding-system-p 'big5-hkscs)
150 '((big5-hkscs . big5)))
129 ;; Windows-1252 is actually a superset of Latin-1. See also 151 ;; Windows-1252 is actually a superset of Latin-1. See also
130 ;; `gnus-article-dumbquotes-map'. 152 ;; `gnus-article-dumbquotes-map'.
131 ,@(unless (mm-coding-system-p 'windows-1252) 153 ,@(unless (mm-coding-system-p 'windows-1252)
132 (if (mm-coding-system-p 'cp1252) 154 (if (mm-coding-system-p 'cp1252)
133 '((windows-1252 . cp1252)) 155 '((windows-1252 . cp1252))
134 '((windows-1252 . iso-8859-1)))) 156 '((windows-1252 . iso-8859-1))))
135 ;; Windows-1250 is a variant of Latin-2 heavily used by Microsoft 157 ;; Windows-1250 is a variant of Latin-2 heavily used by Microsoft
136 ;; Outlook users in Czech republic. Use this to allow reading of their 158 ;; Outlook users in Czech republic. Use this to allow reading of their
137 ;; e-mails. cp1250 should be defined by M-x codepage-setup. 159 ;; e-mails. cp1250 should be defined by M-x codepage-setup.
138
139 ;; This is not TRT, the MIME name, windows-1250, should be an
140 ;; alias, and cp1250 should have a mime-charset property, per
141 ;; code-page.el. -- fx
142 ,@(if (and (not (mm-coding-system-p 'windows-1250)) 160 ,@(if (and (not (mm-coding-system-p 'windows-1250))
143 (mm-coding-system-p 'cp1250)) 161 (mm-coding-system-p 'cp1250))
144 '((windows-1250 . cp1250))) 162 '((windows-1250 . cp1250)))
145 ) 163 )
146 "A mapping from invalid charset names to the real charset names.") 164 "A mapping from invalid charset names to the real charset names.")
162 (defvar mm-text-coding-system-for-write nil 180 (defvar mm-text-coding-system-for-write nil
163 "Text coding system for write.") 181 "Text coding system for write.")
164 182
165 (defvar mm-auto-save-coding-system 183 (defvar mm-auto-save-coding-system
166 (cond 184 (cond
167 ((mm-coding-system-p 'utf-8-emacs) 185 ((mm-coding-system-p 'utf-8-emacs) ; Mule 7
168 (if (memq system-type '(windows-nt ms-dos ms-windows)) 186 (if (memq system-type '(windows-nt ms-dos ms-windows))
169 (if (mm-coding-system-p 'utf-8-emacs-dos) 187 (if (mm-coding-system-p 'utf-8-emacs-dos)
170 'utf-8-emacs-dos mm-binary-coding-system) 188 'utf-8-emacs-dos mm-binary-coding-system)
171 'utf-8-emacs)) 189 'utf-8-emacs))
172 ((mm-coding-system-p 'emacs-mule) 190 ((mm-coding-system-p 'emacs-mule)
284 (car cs)))))) 302 (car cs))))))
285 '(gnus-charset 0))) 303 '(gnus-charset 0)))
286 mm-iso-8859-15-compatible)) 304 mm-iso-8859-15-compatible))
287 "A table of the difference character between ISO-8859-X and ISO-8859-15.") 305 "A table of the difference character between ISO-8859-X and ISO-8859-15.")
288 306
289 (defvar mm-coding-system-priorities nil 307 (defcustom mm-coding-system-priorities
290 "Preferred coding systems for encoding outgoing mails. 308 (if (boundp 'current-language-environment)
291 309 (let ((lang (symbol-value 'current-language-environment)))
292 More than one suitable coding systems may be found for some texts. By 310 (cond ((string= lang "Japanese")
293 default, a coding system with the highest priority is used to encode 311 ;; Japanese users may prefer iso-2022-jp to shift-jis.
294 outgoing mails (see `sort-coding-systems'). If this variable is set, 312 '(iso-2022-jp iso-2022-jp-2 japanese-shift-jis
295 it overrides the default priority. For example, Japanese users may 313 iso-latin-1 utf-8)))))
296 prefer iso-2022-jp to japanese-shift-jis: 314 "Preferred coding systems for encoding outgoing messages.
297 315
298 \(setq mm-coding-system-priorities 316 More than one suitable coding system may be found for some text.
299 '(iso-2022-jp iso-2022-jp-2 japanese-shift-jis utf-8)) 317 By default, the coding system with the highest priority is used
300 ") 318 to encode outgoing messages (see `sort-coding-systems'). If this
301 319 variable is set, it overrides the default priority."
302 ;; Why on earth was this broken out? -- fx 320 :type '(repeat (symbol :tag "Coding system"))
321 :group 'mime)
322
323 ;; ??
303 (defvar mm-use-find-coding-systems-region 324 (defvar mm-use-find-coding-systems-region
304 (fboundp 'find-coding-systems-region) 325 (fboundp 'find-coding-systems-region)
305 "Use `find-coding-systems-region' to find proper coding systems.") 326 "Use `find-coding-systems-region' to find proper coding systems.
327
328 Setting it to nil is useful on Emacsen supporting Unicode if sending
329 mail with multiple parts is preferred to sending a Unicode one.")
306 330
307 ;;; Internal variables: 331 ;;; Internal variables:
308 332
309 ;;; Functions: 333 ;;; Functions:
310 334
311 (defun mm-mule-charset-to-mime-charset (charset) 335 (defun mm-mule-charset-to-mime-charset (charset)
312 "Return the MIME charset corresponding to the given Mule CHARSET." 336 "Return the MIME charset corresponding to the given Mule CHARSET."
313 (if (fboundp 'find-coding-systems-for-charsets) 337 (if (and (fboundp 'find-coding-systems-for-charsets)
338 (fboundp 'sort-coding-systems))
314 (let (mime) 339 (let (mime)
315 (dolist (cs (find-coding-systems-for-charsets (list charset))) 340 (dolist (cs (sort-coding-systems
341 (copy-sequence
342 (find-coding-systems-for-charsets (list charset)))))
316 (unless mime 343 (unless mime
317 (when cs 344 (when cs
318 (setq mime (or (coding-system-get cs :mime-charset) 345 (setq mime (or (coding-system-get cs :mime-charset)
319 (coding-system-get cs 'mime-charset)))))) 346 (coding-system-get cs 'mime-charset))))))
320 mime) 347 mime)
338 (setq charset (intern (format "%s-%s" charset lbt)))) 365 (setq charset (intern (format "%s-%s" charset lbt))))
339 (cond 366 (cond
340 ((null charset) 367 ((null charset)
341 charset) 368 charset)
342 ;; Running in a non-MULE environment. 369 ;; Running in a non-MULE environment.
343 ((null (mm-get-coding-system-list)) 370 ((or (null (mm-get-coding-system-list))
371 (not (fboundp 'coding-system-get)))
344 charset) 372 charset)
345 ;; ascii 373 ;; ascii
346 ((eq charset 'us-ascii) 374 ((eq charset 'us-ascii)
347 'ascii) 375 'ascii)
348 ;; Check to see whether we can handle this charset. (This depends 376 ;; Check to see whether we can handle this charset. (This depends
354 ;;; (eq charset (coding-system-get charset 'mime-charset)) 382 ;;; (eq charset (coding-system-get charset 'mime-charset))
355 ) 383 )
356 charset) 384 charset)
357 ;; Translate invalid charsets. 385 ;; Translate invalid charsets.
358 ((let ((cs (cdr (assq charset mm-charset-synonym-alist)))) 386 ((let ((cs (cdr (assq charset mm-charset-synonym-alist))))
359 (and cs (mm-coding-system-p charset) cs))) 387 (and cs (mm-coding-system-p cs) cs)))
360 ;; Last resort: search the coding system list for entries which 388 ;; Last resort: search the coding system list for entries which
361 ;; have the right mime-charset in case the canonical name isn't 389 ;; have the right mime-charset in case the canonical name isn't
362 ;; defined (though it should be). 390 ;; defined (though it should be).
363 ((let (cs) 391 ((let (cs)
364 ;; mm-get-coding-system-list returns a list of cs without lbt. 392 ;; mm-get-coding-system-list returns a list of cs without lbt.
383 (if mm-emacs-mule 411 (if mm-emacs-mule
384 (defun mm-enable-multibyte () 412 (defun mm-enable-multibyte ()
385 "Set the multibyte flag of the current buffer. 413 "Set the multibyte flag of the current buffer.
386 Only do this if the default value of `enable-multibyte-characters' is 414 Only do this if the default value of `enable-multibyte-characters' is
387 non-nil. This is a no-op in XEmacs." 415 non-nil. This is a no-op in XEmacs."
388 (set-buffer-multibyte t)) 416 (set-buffer-multibyte 'to))
389 (defalias 'mm-enable-multibyte 'ignore)) 417 (defalias 'mm-enable-multibyte 'ignore))
390 418
391 (if mm-emacs-mule 419 (if mm-emacs-mule
392 (defun mm-disable-multibyte () 420 (defun mm-disable-multibyte ()
393 "Unset the multibyte flag of in the current buffer. 421 "Unset the multibyte flag of in the current buffer.
397 425
398 (defun mm-preferred-coding-system (charset) 426 (defun mm-preferred-coding-system (charset)
399 ;; A typo in some Emacs versions. 427 ;; A typo in some Emacs versions.
400 (or (get-charset-property charset 'preferred-coding-system) 428 (or (get-charset-property charset 'preferred-coding-system)
401 (get-charset-property charset 'prefered-coding-system))) 429 (get-charset-property charset 'prefered-coding-system)))
430
431 ;; Mule charsets shouldn't be used.
432 (defsubst mm-guess-charset ()
433 "Guess Mule charset from the language environment."
434 (or
435 mail-parse-mule-charset ;; cached mule-charset
436 (progn
437 (setq mail-parse-mule-charset
438 (and (boundp 'current-language-environment)
439 (car (last
440 (assq 'charset
441 (assoc current-language-environment
442 language-info-alist))))))
443 (if (or (not mail-parse-mule-charset)
444 (eq mail-parse-mule-charset 'ascii))
445 (setq mail-parse-mule-charset
446 (or (car (last (assq mail-parse-charset
447 mm-mime-mule-charset-alist)))
448 ;; default
449 'latin-iso8859-1)))
450 mail-parse-mule-charset)))
402 451
403 (defun mm-charset-after (&optional pos) 452 (defun mm-charset-after (&optional pos)
404 "Return charset of a character in current buffer at position POS. 453 "Return charset of a character in current buffer at position POS.
405 If POS is nil, it defauls to the current point. 454 If POS is nil, it defauls to the current point.
406 If POS is out of range, the value is nil. 455 If POS is out of range, the value is nil.
414 (let ((p (or pos (point)))) 463 (let ((p (or pos (point))))
415 (cadr (find-charset-region p (1+ p)))) 464 (cadr (find-charset-region p (1+ p))))
416 (if (and charset (not (memq charset '(ascii eight-bit-control 465 (if (and charset (not (memq charset '(ascii eight-bit-control
417 eight-bit-graphic)))) 466 eight-bit-graphic))))
418 charset 467 charset
419 (or 468 (mm-guess-charset))))))
420 mail-parse-mule-charset ;; cached mule-charset
421 (progn
422 (setq mail-parse-mule-charset
423 (and (boundp 'current-language-environment)
424 (car (last
425 (assq 'charset
426 (assoc current-language-environment
427 language-info-alist))))))
428 (if (or (not mail-parse-mule-charset)
429 (eq mail-parse-mule-charset 'ascii))
430 (setq mail-parse-mule-charset
431 (or (car (last (assq mail-parse-charset
432 mm-mime-mule-charset-alist)))
433 ;; Fixme: don't fix that!
434 'latin-iso8859-1)))
435 mail-parse-mule-charset)))))))
436 469
437 (defun mm-mime-charset (charset) 470 (defun mm-mime-charset (charset)
438 "Return the MIME charset corresponding to the given Mule CHARSET." 471 "Return the MIME charset corresponding to the given Mule CHARSET."
439 (if (eq charset 'unknown) 472 (if (eq charset 'unknown)
440 (error "The message contains non-printable characters, please use attachment")) 473 (error "The message contains non-printable characters, please use attachment"))
460 (setq head (car list)) 493 (setq head (car list))
461 (setq list (delete head list)) 494 (setq list (delete head list))
462 (setq result (cons head result))) 495 (setq result (cons head result)))
463 (nreverse result))) 496 (nreverse result)))
464 497
465 ;; It's not clear whether this is supposed to mean the global or local 498 ;; Fixme: This is used in places when it should be testing the
466 ;; setting. I think it's used inconsistently. -- fx 499 ;; default multibyteness. See mm-default-multibyte-p.
467 (defsubst mm-multibyte-p () 500 (eval-and-compile
468 "Say whether multibyte is enabled."
469 (if (and (not (featurep 'xemacs)) 501 (if (and (not (featurep 'xemacs))
470 (boundp 'enable-multibyte-characters)) 502 (boundp 'enable-multibyte-characters))
471 enable-multibyte-characters 503 (defun mm-multibyte-p ()
472 (featurep 'mule))) 504 "Non-nil if multibyte is enabled in the current buffer."
505 enable-multibyte-characters)
506 (defun mm-multibyte-p () (featurep 'mule))))
507
508 (defun mm-default-multibyte-p ()
509 "Return non-nil if the session is multibyte.
510 This affects whether coding conversion should be attempted generally."
511 (if (featurep 'mule)
512 (if (boundp 'default-enable-multibyte-characters)
513 default-enable-multibyte-characters
514 t)))
473 515
474 (defun mm-iso-8859-x-to-15-region (&optional b e) 516 (defun mm-iso-8859-x-to-15-region (&optional b e)
475 (if (fboundp 'char-charset) 517 (if (fboundp 'char-charset)
476 (let (charset item c inconvertible) 518 (let (charset item c inconvertible)
477 (save-restriction 519 (save-restriction
485 (forward-char)) 527 (forward-char))
486 ((memq c (cdr (cdr item))) 528 ((memq c (cdr (cdr item)))
487 (setq inconvertible t) 529 (setq inconvertible t)
488 (forward-char)) 530 (forward-char))
489 (t 531 (t
490 (insert (prog1 (+ c (car (cdr item))) (delete-char 1)))) 532 (insert-before-markers (prog1 (+ c (car (cdr item)))
491 (skip-chars-forward "\0-\177")))) 533 (delete-char 1)))))
534 (skip-chars-forward "\0-\177")))
492 (not inconvertible)))) 535 (not inconvertible))))
493 536
494 (defun mm-sort-coding-systems-predicate (a b) 537 (defun mm-sort-coding-systems-predicate (a b)
495 (> (length (memq a mm-coding-system-priorities)) 538 (let ((priorities
496 (length (memq b mm-coding-system-priorities)))) 539 (mapcar (lambda (cs)
540 ;; Note: invalid entries are dropped silently
541 (and (coding-system-p cs)
542 (coding-system-base cs)))
543 mm-coding-system-priorities)))
544 (> (length (memq a priorities))
545 (length (memq b priorities)))))
497 546
498 (defun mm-find-mime-charset-region (b e &optional hack-charsets) 547 (defun mm-find-mime-charset-region (b e &optional hack-charsets)
499 "Return the MIME charsets needed to encode the region between B and E. 548 "Return the MIME charsets needed to encode the region between B and E.
500 nil means ASCII, a single-element list represents an appropriate MIME 549 nil means ASCII, a single-element list represents an appropriate MIME
501 charset, and a longer list means no appropriate charset." 550 charset, and a longer list means no appropriate charset."
507 ;; system that has one. 556 ;; system that has one.
508 (let ((systems (find-coding-systems-region b e))) 557 (let ((systems (find-coding-systems-region b e)))
509 (when mm-coding-system-priorities 558 (when mm-coding-system-priorities
510 (setq systems 559 (setq systems
511 (sort systems 'mm-sort-coding-systems-predicate))) 560 (sort systems 'mm-sort-coding-systems-predicate)))
512 ;; Fixme: The `mime-charset' (`x-ctext') of `compound-text'
513 ;; is not in the IANA list.
514 (setq systems (delq 'compound-text systems)) 561 (setq systems (delq 'compound-text systems))
515 (unless (equal systems '(undecided)) 562 (unless (equal systems '(undecided))
516 (while systems 563 (while systems
517 (let* ((head (pop systems)) 564 (let* ((head (pop systems))
518 (cs (or (coding-system-get head :mime-charset) 565 (cs (or (coding-system-get head :mime-charset)
519 (coding-system-get head 'mime-charset)))) 566 (coding-system-get head 'mime-charset))))
520 (if cs 567 ;; The mime-charset (`x-ctext') of
568 ;; `compound-text' is not in the IANA list. We
569 ;; shouldn't normally use anything here with a
570 ;; mime-charset having an `x-' prefix.
571 ;; Fixme: Allow this to be overridden, since
572 ;; there is existing use of x-ctext.
573 ;; Also people apparently need the coding system
574 ;; `iso-2022-jp-3' (which Mule-UCS defines with
575 ;; mime-charset, though it's not valid).
576 (if (and cs
577 (not (string-match "^[Xx]-" (symbol-name cs)))
578 ;; UTF-16 of any variety is invalid for
579 ;; text parts and, unfortunately, has
580 ;; mime-charset defined both in Mule-UCS
581 ;; and versions of Emacs. (The name
582 ;; might be `mule-utf-16...' or
583 ;; `utf-16...'.)
584 (not (string-match "utf-16" (symbol-name cs))))
521 (setq systems nil 585 (setq systems nil
522 charsets (list cs)))))) 586 charsets (list cs))))))
523 charsets)) 587 charsets))
524 ;; Otherwise we're not multibyte, XEmacs or a single coding 588 ;; Otherwise we're not multibyte, we're XEmacs, or a single
525 ;; system won't cover it. 589 ;; coding system won't cover it.
526 (setq charsets 590 (setq charsets
527 (mm-delete-duplicates 591 (mm-delete-duplicates
528 (mapcar 'mm-mime-charset 592 (mapcar 'mm-mime-charset
529 (delq 'ascii 593 (delq 'ascii
530 (mm-find-charset-region b e)))))) 594 (mm-find-charset-region b e))))))
531 (if (and (memq 'iso-8859-15 charsets) 595 (if (and (> (length charsets) 1)
596 (memq 'iso-8859-15 charsets)
532 (memq 'iso-8859-15 hack-charsets) 597 (memq 'iso-8859-15 hack-charsets)
533 (save-excursion (mm-iso-8859-x-to-15-region b e))) 598 (save-excursion (mm-iso-8859-x-to-15-region b e)))
534 (mapcar (lambda (x) (setq charsets (delq (car x) charsets))) 599 (mapcar (lambda (x) (setq charsets (delq (car x) charsets)))
535 mm-iso-8859-15-compatible)) 600 mm-iso-8859-15-compatible))
536 (if (and (memq 'iso-2022-jp-2 charsets) 601 (if (and (memq 'iso-2022-jp-2 charsets)
543 Use unibyte mode for this." 608 Use unibyte mode for this."
544 `(let (default-enable-multibyte-characters) 609 `(let (default-enable-multibyte-characters)
545 (with-temp-buffer ,@forms))) 610 (with-temp-buffer ,@forms)))
546 (put 'mm-with-unibyte-buffer 'lisp-indent-function 0) 611 (put 'mm-with-unibyte-buffer 'lisp-indent-function 0)
547 (put 'mm-with-unibyte-buffer 'edebug-form-spec '(body)) 612 (put 'mm-with-unibyte-buffer 'edebug-form-spec '(body))
613
614 (defmacro mm-with-multibyte-buffer (&rest forms)
615 "Create a temporary buffer, and evaluate FORMS there like `progn'.
616 Use multibyte mode for this."
617 `(let ((default-enable-multibyte-characters t))
618 (with-temp-buffer ,@forms)))
619 (put 'mm-with-multibyte-buffer 'lisp-indent-function 0)
620 (put 'mm-with-multibyte-buffer 'edebug-form-spec '(body))
548 621
549 (defmacro mm-with-unibyte-current-buffer (&rest forms) 622 (defmacro mm-with-unibyte-current-buffer (&rest forms)
550 "Evaluate FORMS with current buffer temporarily made unibyte. 623 "Evaluate FORMS with current buffer temporarily made unibyte.
551 Also bind `default-enable-multibyte-characters' to nil. 624 Also bind `default-enable-multibyte-characters' to nil.
552 Equivalent to `progn' in XEmacs" 625 Equivalent to `progn' in XEmacs"
565 ,@forms)))) 638 ,@forms))))
566 (put 'mm-with-unibyte-current-buffer 'lisp-indent-function 0) 639 (put 'mm-with-unibyte-current-buffer 'lisp-indent-function 0)
567 (put 'mm-with-unibyte-current-buffer 'edebug-form-spec '(body)) 640 (put 'mm-with-unibyte-current-buffer 'edebug-form-spec '(body))
568 641
569 (defmacro mm-with-unibyte (&rest forms) 642 (defmacro mm-with-unibyte (&rest forms)
570 "Eval the FORMS with the default value of `enable-multibyte-characters' nil, ." 643 "Eval the FORMS with the default value of `enable-multibyte-characters' nil."
571 `(let (default-enable-multibyte-characters) 644 `(let (default-enable-multibyte-characters)
572 ,@forms)) 645 ,@forms))
573 (put 'mm-with-unibyte 'lisp-indent-function 0) 646 (put 'mm-with-unibyte 'lisp-indent-function 0)
574 (put 'mm-with-unibyte 'edebug-form-spec '(body)) 647 (put 'mm-with-unibyte 'edebug-form-spec '(body))
648
649 (defmacro mm-with-multibyte (&rest forms)
650 "Eval the FORMS with the default value of `enable-multibyte-characters' t."
651 `(let ((default-enable-multibyte-characters t))
652 ,@forms))
653 (put 'mm-with-multibyte 'lisp-indent-function 0)
654 (put 'mm-with-multibyte 'edebug-form-spec '(body))
575 655
576 (defun mm-find-charset-region (b e) 656 (defun mm-find-charset-region (b e)
577 "Return a list of Emacs charsets in the region B to E." 657 "Return a list of Emacs charsets in the region B to E."
578 (cond 658 (cond
579 ((and (mm-multibyte-p) 659 ((and (mm-multibyte-p)
636 '(jka-compr-handler image-file-handler) 716 '(jka-compr-handler image-file-handler)
637 "A list of handlers doing (un)compression (etc) thingies.") 717 "A list of handlers doing (un)compression (etc) thingies.")
638 718
639 (defun mm-insert-file-contents (filename &optional visit beg end replace 719 (defun mm-insert-file-contents (filename &optional visit beg end replace
640 inhibit) 720 inhibit)
641 "Like `insert-file-contents', q.v., but only reads in the file. 721 "Like `insert-file-contents', but only reads in the file.
642 A buffer may be modified in several ways after reading into the buffer due 722 A buffer may be modified in several ways after reading into the buffer due
643 to advanced Emacs features, such as file-name-handlers, format decoding, 723 to advanced Emacs features, such as file-name-handlers, format decoding,
644 find-file-hooks, etc. 724 `find-file-hooks', etc.
645 If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'. 725 If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'.
646 This function ensures that none of these modifications will take place." 726 This function ensures that none of these modifications will take place."
647 (let ((format-alist nil) 727 (let ((format-alist nil)
648 (auto-mode-alist (if inhibit nil (mm-auto-mode-alist))) 728 (auto-mode-alist (if inhibit nil (mm-auto-mode-alist)))
649 (default-major-mode 'fundamental-mode) 729 (default-major-mode 'fundamental-mode)
666 When called from a function, expects three arguments, 746 When called from a function, expects three arguments,
667 START, END and FILENAME. START and END are buffer positions 747 START, END and FILENAME. START and END are buffer positions
668 saying what text to write. 748 saying what text to write.
669 Optional fourth argument specifies the coding system to use when 749 Optional fourth argument specifies the coding system to use when
670 encoding the file. 750 encoding the file.
671 If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers." 751 If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'."
672 (let ((coding-system-for-write 752 (let ((coding-system-for-write
673 (or codesys mm-text-coding-system-for-write 753 (or codesys mm-text-coding-system-for-write
674 mm-text-coding-system)) 754 mm-text-coding-system))
675 (inhibit-file-name-operation (if inhibit 755 (inhibit-file-name-operation (if inhibit
676 'append-to-file 756 'append-to-file
678 (inhibit-file-name-handlers 758 (inhibit-file-name-handlers
679 (if inhibit 759 (if inhibit
680 (append mm-inhibit-file-name-handlers 760 (append mm-inhibit-file-name-handlers
681 inhibit-file-name-handlers) 761 inhibit-file-name-handlers)
682 inhibit-file-name-handlers))) 762 inhibit-file-name-handlers)))
683 (append-to-file start end filename))) 763 (write-region start end filename t 'no-message)
764 (message "Appended to %s" filename)))
684 765
685 (defun mm-write-region (start end filename &optional append visit lockname 766 (defun mm-write-region (start end filename &optional append visit lockname
686 coding-system inhibit) 767 coding-system inhibit)
687 768
688 "Like `write-region'. 769 "Like `write-region'.
689 If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers." 770 If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'."
690 (let ((coding-system-for-write 771 (let ((coding-system-for-write
691 (or coding-system mm-text-coding-system-for-write 772 (or coding-system mm-text-coding-system-for-write
692 mm-text-coding-system)) 773 mm-text-coding-system))
693 (inhibit-file-name-operation (if inhibit 774 (inhibit-file-name-operation (if inhibit
694 'write-region 775 'write-region
708 (directory-file-name path)) 789 (directory-file-name path))
709 "etc/" (or package "gnus/")))) 790 "etc/" (or package "gnus/"))))
710 (push dir result)) 791 (push dir result))
711 (push path result)))) 792 (push path result))))
712 793
713 ;; It is not a MIME function, but some MIME functions use it. 794 ;; Fixme: This doesn't look useful where it's used.
714 (defalias 'mm-make-temp-file 795 (if (fboundp 'detect-coding-region)
715 (if (fboundp 'make-temp-file) 796 (defun mm-detect-coding-region (start end)
716 'make-temp-file 797 "Like `detect-coding-region' except returning the best one."
717 (lambda (prefix &optional dir-flag) 798 (let ((coding-systems
718 (let ((file (expand-file-name 799 (detect-coding-region (point) (point-max))))
719 (make-temp-name prefix) 800 (or (car-safe coding-systems)
720 (if (fboundp 'temp-directory) 801 coding-systems)))
721 (temp-directory) 802 (defun mm-detect-coding-region (start end)
722 temporary-file-directory)))) 803 (let ((point (point)))
723 (if dir-flag 804 (goto-char start)
724 (make-directory file)) 805 (skip-chars-forward "\0-\177" end)
725 file)))) 806 (prog1
807 (if (eq (point) end) 'ascii (mm-guess-charset))
808 (goto-char point)))))
809
810 (if (fboundp 'coding-system-get)
811 (defun mm-detect-mime-charset-region (start end)
812 "Detect MIME charset of the text in the region between START and END."
813 (let ((cs (mm-detect-coding-region start end)))
814 (coding-system-get cs 'mime-charset)))
815 (defun mm-detect-mime-charset-region (start end)
816 "Detect MIME charset of the text in the region between START and END."
817 (let ((cs (mm-detect-coding-region start end)))
818 cs)))
819
726 820
727 (provide 'mm-util) 821 (provide 'mm-util)
728 822
729 ;;; arch-tag: 94dc5388-825d-4fd1-bfa5-2100aa351238 823 ;;; arch-tag: 94dc5388-825d-4fd1-bfa5-2100aa351238
730 ;;; mm-util.el ends here 824 ;;; mm-util.el ends here