Mercurial > emacs
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 |