1 ;;; mel.el : a MIME encoding/decoding library
3 ;; Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
5 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
6 ;; modified by Shuhei KOBAYASHI <shuhei-k@jaist.ac.jp>
8 ;; Keywords: MIME, Base64, Quoted-Printable, uuencode, gzip64
10 ;; This file is part of MEL (MIME Encoding Library).
12 ;; This program is free software; you can redistribute it and/or
13 ;; modify it under the terms of the GNU General Public License as
14 ;; published by the Free Software Foundation; either version 2, or (at
15 ;; your option) any later version.
17 ;; This program is distributed in the hope that it will be useful, but
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;; General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 ;; Boston, MA 02111-1307, USA.
35 (defvar base64-internal-encoding-limit 1000
36 "*limit size to use internal base64 encoder.
37 If size of input to encode is larger than this limit,
38 external encoder is called.")
40 (defvar base64-internal-decoding-limit 1000
41 "*limit size to use internal base64 decoder.
42 size of input to decode is larger than this limit,
43 external decoder is called.")
45 (defvar quoted-printable-internal-encoding-limit
46 (if (and (featurep 'xemacs)(featurep 'mule))
49 (if (exec-installed-p "mmencode")
51 (message "Don't found external encoder for Quoted-Printable!")
53 "*limit size to use internal quoted-printable encoder.
54 If size of input to encode is larger than this limit,
55 external encoder is called.")
57 (defvar quoted-printable-internal-decoding-limit nil
58 "*limit size to use internal quoted-printable decoder.
59 If size of input to decode is larger than this limit,
60 external decoder is called.")
67 (defvar base64-dl-module
68 (and (fboundp 'dynamic-link)
69 (let ((path (expand-file-name "base64.so" exec-directory)))
70 (and (file-exists-p path)
73 (when base64-dl-module
74 (autoload 'base64-dl-encode-string "mel-dl"
75 "Encode STRING to base64, and return the result.")
76 (autoload 'base64-dl-decode-string "mel-dl"
77 "Decode STRING which is encoded in base64, and return the result.")
78 (autoload 'base64-dl-encode-region "mel-dl"
79 "Encode current region by base64." t)
80 (autoload 'base64-dl-decode-region "mel-dl"
81 "Decode current region by base64." t))
84 (autoload 'base64-internal-encode-string "mel-b"
85 "Encode STRING to base64, and return the result.")
86 (autoload 'base64-internal-decode-string "mel-b"
87 "Decode STRING which is encoded in base64, and return the result.")
88 (autoload 'base64-internal-encode-region "mel-b"
89 "Encode current region by base64." t)
90 (autoload 'base64-internal-decode-region "mel-b"
91 "Decode current region by base64." t)
92 (autoload 'base64-internal-insert-encoded-file "mel-b"
93 "Encode contents of file to base64, and insert the result." t)
94 (autoload 'base64-internal-write-decoded-region "mel-b"
95 "Decode and write current region encoded by base64 into FILENAME." t)
97 (autoload 'base64-external-encode-string "mel-b"
98 "Encode STRING to base64, and return the result.")
99 (autoload 'base64-external-decode-string "mel-b"
100 "Decode STRING which is encoded in base64, and return the result.")
101 (autoload 'base64-external-encode-region "mel-b"
102 "Encode current region by base64." t)
103 (autoload 'base64-external-decode-region "mel-b"
104 "Decode current region by base64." t)
105 (autoload 'base64-external-insert-encoded-file "mel-b"
106 "Encode contents of file to base64, and insert the result." t)
107 (autoload 'base64-external-write-decoded-region "mel-b"
108 "Decode and write current region encoded by base64 into FILENAME." t)
111 (autoload 'base64-internal-encoded-length "mel-b")
114 (autoload 'quoted-printable-internal-encode-string "mel-q"
115 "Encode STRING to quoted-printable, and return the result.")
116 (autoload 'quoted-printable-internal-decode-string "mel-q"
117 "Decode STRING which is encoded in quoted-printable, and return the result.")
118 (autoload 'quoted-printable-internal-encode-region "mel-q"
119 "Encode current region by Quoted-Printable." t)
120 (autoload 'quoted-printable-internal-decode-region "mel-q"
121 "Decode current region by Quoted-Printable." t)
123 (autoload 'quoted-printable-external-encode-string "mel-q"
124 "Encode STRING to quoted-printable, and return the result.")
125 (autoload 'quoted-printable-external-decode-string "mel-q"
126 "Decode STRING which is encoded in quoted-printable, and return the result.")
127 (autoload 'quoted-printable-external-encode-region "mel-q"
128 "Encode current region by Quoted-Printable." t)
129 (autoload 'quoted-printable-external-decode-region "mel-q"
130 "Decode current region by Quoted-Printable." t)
132 (autoload 'quoted-printable-external-insert-encoded-file "mel-q"
133 "Encode contents of file to quoted-printable, and insert the result." t)
134 (autoload 'quoted-printable-external-write-decoded-region "mel-q"
135 "Decode and write current region encoded by quoted-printable into FILENAME."
139 (autoload 'q-encoding-internal-encode-string "mel-q"
140 "Encode STRING to Q-encoding of encoded-word, and return the result.")
141 (autoload 'q-encoding-internal-decode-string "mel-q"
142 "Decode STRING which is encoded in Q-encoding and return the result.")
143 (autoload 'q-encoding-internal-encoded-length "mel-q")
146 (autoload 'uuencode-external-encode-region "mel-u"
147 "Encode current region by unofficial uuencode format." t)
148 (autoload 'uuencode-external-decode-region "mel-u"
149 "Decode current region by unofficial uuencode format." t)
150 (autoload 'uuencode-external-insert-encoded-file "mel-u"
151 "Insert file encoded by unofficial uuencode format." t)
152 (autoload 'uuencode-external-write-decoded-region "mel-u"
153 "Decode and write current region encoded by uuencode into FILENAME." t)
156 (autoload 'gzip64-external-encode-region "mel-g"
157 "Encode current region by unofficial x-gzip64 format." t)
158 (autoload 'gzip64-external-decode-region "mel-g"
159 "Decode current region by unofficial x-gzip64 format." t)
160 (autoload 'gzip64-external-insert-encoded-file "mel-g"
161 "Insert file encoded by unofficial gzip64 format." t)
162 (autoload 'gzip64-external-write-decoded-region "mel-g"
163 "Decode and write current region encoded by gzip64 into FILENAME." t)
166 (when (fboundp 'make-ccl-coding-system)
167 (unless (and (boundp 'ccl-encoder-eof-block-is-broken)
168 ccl-encoder-eof-block-is-broken)
169 (autoload 'base64-ccl-encode-string "mel-ccl"
170 "Encode STRING with base64 encoding.")
171 (autoload 'base64-ccl-encode-region "mel-ccl"
172 "Encode region from START to END with base64 encoding." t)
173 (autoload 'base64-ccl-insert-encoded-file "mel-ccl"
174 "Encode contents of file FILENAME to base64, and insert the result." t))
176 (autoload 'base64-ccl-decode-string "mel-ccl"
177 "Decode base64 encoded STRING")
178 (autoload 'base64-ccl-decode-region "mel-ccl"
179 "Decode base64 encoded STRING" t)
180 (autoload 'base64-ccl-write-decoded-region "mel-ccl"
181 "Decode the region from START to END and write out to FILENAME." t)
183 (unless (and (boundp 'ccl-encoder-eof-block-is-broken)
184 ccl-encoder-eof-block-is-broken)
185 (autoload 'quoted-printable-ccl-encode-string "mel-ccl"
186 "Encode STRING with quoted-printable encoding.")
187 (autoload 'quoted-printable-ccl-encode-region "mel-ccl"
188 "Encode the region from START to END with quoted-printable
190 (autoload 'quoted-printable-ccl-insert-encoded-file "mel-ccl"
191 "Encode contents of the file named as FILENAME, and insert it." t))
193 (autoload 'quoted-printable-ccl-decode-string "mel-ccl"
194 "Decode quoted-printable encoded STRING.")
195 (autoload 'quoted-printable-ccl-decode-region "mel-ccl"
196 "Decode the region from START to END with quoted-printable
198 (autoload 'quoted-printable-ccl-write-decoded-region "mel-ccl"
199 "Decode quoted-printable encoded current region and write out to FILENAME." t)
201 (autoload 'q-encoding-ccl-encode-string "mel-ccl"
202 "Encode STRING to Q-encoding of encoded-word, and return the result.
203 MODE allows `text', `comment', `phrase' or nil. Default value is
205 (autoload 'q-encoding-ccl-decode-string "mel-ccl"
206 "Decode Q encoded STRING and return the result.")
208 (unless running-xemacs
209 (autoload 'q-encoding-ccl-encoded-length "mel-ccl"
210 "Encode STRING to Q-encoding of encoded-word, and return the result.
211 MODE allows `text', `comment', `phrase' or nil. Default value is
217 ;;; @ entrance functions.
221 ((fboundp 'base64-dl-encode-string)
222 (defalias 'base64-encode-string 'base64-dl-encode-string))
223 ((fboundp 'base64-ccl-encode-string)
224 (defalias 'base64-encode-string 'base64-ccl-encode-string))
226 (defalias 'base64-encode-string 'base64-internal-encode-string)))
228 (defun base64-internal-external-decode-string (string)
229 "Decode STRING which is encoded in base64, and return the result.
230 This function calls internal base64 decoder if size of STRING is
231 smaller than `base64-internal-decoding-limit', otherwise it calls
232 external base64 decoder specified by `base64-external-decoder'. In
233 this case, you must install the program (maybe mmencode included in
234 metamail or XEmacs package)."
236 (if (and base64-internal-decoding-limit
237 (> (length string) base64-internal-decoding-limit))
238 (base64-external-decode-string string)
239 (base64-internal-decode-string string)))
242 ((fboundp 'base64-dl-decode-string)
243 (defalias 'base64-decode-string 'base64-dl-decode-string))
244 ((fboundp 'base64-ccl-decode-string)
245 (defalias 'base64-decode-string 'base64-ccl-decode-string))
247 (defalias 'base64-decode-string 'base64-internal-external-decode-string)))
249 (defun base64-internal-external-encode-region (start end)
250 "Encode current region by base64.
251 START and END are buffer positions.
252 This function calls internal base64 encoder if size of region is
253 smaller than `base64-internal-encoding-limit', otherwise it calls
254 external base64 encoder specified by `base64-external-encoder'. In
255 this case, you must install the program (maybe mmencode included in
256 metamail or XEmacs package)."
258 (if (and base64-internal-encoding-limit
259 (> (- end start) base64-internal-encoding-limit))
260 (base64-external-encode-region start end)
261 (base64-internal-encode-region start end)))
264 ((fboundp 'base64-dl-encode-region)
265 (defalias 'base64-encode-region 'base64-dl-encode-region)) ; no fold
266 ((fboundp 'base64-ccl-encode-region)
267 (defalias 'base64-encode-region 'base64-ccl-encode-region)) ; LF fold
269 (defalias 'base64-encode-region 'base64-internal-external-encode-region))) ; LF fold
271 (defun base64-internal-external-decode-region (start end)
272 "Decode current region by base64.
273 START and END are buffer positions.
274 This function calls internal base64 decoder if size of region is
275 smaller than `base64-internal-decoding-limit', otherwise it calls
276 external base64 decoder specified by `base64-external-decoder'. In
277 this case, you must install the program (maybe mmencode included in
278 metamail or XEmacs package)."
280 (if (and base64-internal-decoding-limit
281 (> (- end start) base64-internal-decoding-limit))
282 (base64-external-decode-region start end)
283 (base64-internal-decode-region start end)))
286 ((fboundp 'base64-dl-decode-region)
287 (defalias 'base64-decode-region 'base64-dl-decode-region))
288 ((fboundp 'base64-ccl-decode-region)
289 (defalias 'base64-decode-region 'base64-ccl-decode-region))
291 (defalias 'base64-decode-region 'base64-internal-external-decode-region)))
293 (defun base64-internal-external-insert-encoded-file (filename)
294 "Encode contents of file FILENAME to base64, and insert the result.
295 It calls external base64 encoder specified by
296 `base64-external-encoder'. So you must install the program (maybe
297 mmencode included in metamail or XEmacs package)."
298 (interactive (list (read-file-name "Insert encoded file: ")))
299 (if (and base64-internal-encoding-limit
300 (> (nth 7 (file-attributes filename))
301 base64-internal-encoding-limit))
302 (base64-external-insert-encoded-file filename)
303 (base64-internal-insert-encoded-file filename)))
306 ((fboundp 'base64-ccl-insert-encoded-file)
307 (defalias 'base64-insert-encoded-file 'base64-ccl-insert-encoded-file))
309 (defalias 'base64-insert-encoded-file 'base64-internal-external-insert-encoded-file)))
311 (defun base64-internal-external-write-decoded-region (start end filename)
312 "Decode and write current region encoded by base64 into FILENAME.
313 START and END are buffer positions."
315 (list (region-beginning) (region-end)
316 (read-file-name "Write decoded region to file: ")))
317 (if (and base64-internal-decoding-limit
318 (> (- end start) base64-internal-decoding-limit))
319 (base64-external-write-decoded-region start end filename)
320 (base64-internal-write-decoded-region start end filename)))
323 ((fboundp 'base64-ccl-write-decoded-region)
324 (defalias 'base64-write-decoded-region 'base64-ccl-write-decoded-region))
326 (defalias 'base64-write-decoded-region 'base64-internal-external-write-decoded-region)))
330 (defalias 'base64-encoded-length 'base64-internal-encoded-length)))
333 ((fboundp 'quoted-printable-ccl-encode-string)
334 (defalias 'quoted-printable-encode-string 'quoted-printable-ccl-encode-string))
336 (defun quoted-printable-encode-string (string)
337 "Encode STRING to quoted-printable, and return the result."
338 (if (and quoted-printable-internal-encoding-limit
339 (> (length string) quoted-printable-internal-encoding-limit))
340 (quoted-printable-external-encode-string string)
341 (quoted-printable-internal-encode-string string)))))
344 ((fboundp 'quoted-printable-ccl-decode-string)
345 (defalias 'quoted-printable-decode-string 'quoted-printable-ccl-decode-string))
347 (defun quoted-printable-decode-string (string)
348 "Decode STRING which is encoded in quoted-printable, and return the result."
349 (if (and quoted-printable-internal-decoding-limit
350 (> (length string) quoted-printable-internal-decoding-limit))
351 (quoted-printable-external-decode-string string)
352 (quoted-printable-internal-decode-string string)))))
355 ((fboundp 'quoted-printable-ccl-encode-region)
356 (defalias 'quoted-printable-encode-region 'quoted-printable-ccl-encode-region))
358 (defun quoted-printable-encode-region (start end)
359 "Encode current region by quoted-printable.
360 START and END are buffer positions.
361 This function calls internal quoted-printable encoder if size of
362 region is smaller than `quoted-printable-internal-encoding-limit',
363 otherwise it calls external quoted-printable encoder specified by
364 `quoted-printable-external-encoder'. In this case, you must install
365 the program (maybe mmencode included in metamail or XEmacs package)."
367 (if (and quoted-printable-internal-encoding-limit
368 (> (- end start) quoted-printable-internal-encoding-limit))
369 (quoted-printable-external-encode-region start end)
370 (quoted-printable-internal-encode-region start end)
374 ((fboundp 'quoted-printable-ccl-decode-region)
375 (defalias 'quoted-printable-decode-region 'quoted-printable-ccl-decode-region))
377 (defun quoted-printable-decode-region (start end)
378 "Decode current region by quoted-printable.
379 START and END are buffer positions.
380 This function calls internal quoted-printable decoder if size of
381 region is smaller than `quoted-printable-internal-decoding-limit',
382 otherwise it calls external quoted-printable decoder specified by
383 `quoted-printable-external-decoder'. In this case, you must install
384 the program (maybe mmencode included in metamail or XEmacs package)."
386 (if (and quoted-printable-internal-decoding-limit
387 (> (- end start) quoted-printable-internal-decoding-limit))
388 (quoted-printable-external-decode-region start end)
389 (quoted-printable-internal-decode-region start end)
393 ((fboundp 'quoted-printable-ccl-insert-encoded-file)
394 (defalias 'quoted-printable-insert-encoded-file 'quoted-printable-ccl-insert-encoded-file))
396 (defalias 'quoted-printable-insert-encoded-file 'quoted-printable-external-insert-encoded-file)))
399 ((fboundp 'quoted-printable-ccl-write-decoded-region)
400 (defalias 'quoted-printable-write-decoded-region 'quoted-printable-ccl-write-decoded-region))
402 (defalias 'quoted-printable-write-decoded-region 'quoted-printable-external-write-decoded-region)))
405 ((fboundp 'q-encoding-ccl-encode-string)
406 (defalias 'q-encoding-encode-string 'q-encoding-ccl-encode-string))
408 (defalias 'q-encoding-encode-string 'q-encoding-internal-encode-string)))
411 ((fboundp 'q-encoding-ccl-decode-string)
412 (defalias 'q-encoding-decode-string 'q-encoding-ccl-decode-string))
414 (defalias 'q-encoding-decode-string 'q-encoding-internal-decode-string)))
417 ((fboundp 'q-encoding-ccl-encoded-length)
418 (defalias 'q-encoding-encoded-length 'q-encoding-ccl-encoded-length))
420 (defalias 'q-encoding-encoded-length 'q-encoding-internal-encoded-length)))
424 (defalias 'uuencode-encode-region 'uuencode-external-encode-region)))
428 (defalias 'uuencode-decode-region 'uuencode-external-decode-region)))
432 (defalias 'uuencode-insert-encoded-file 'uuencode-external-insert-encoded-file)))
436 (defalias 'uuencode-write-decoded-region 'uuencode-external-write-decoded-region)))
440 (defalias 'gzip64-encode-region 'gzip64-external-encode-region)))
444 (defalias 'gzip64-decode-region 'gzip64-external-decode-region)))
448 (defalias 'gzip64-insert-encoded-file 'gzip64-external-insert-encoded-file)))
452 (defalias 'gzip64-write-decoded-region 'gzip64-external-write-decoded-region)))
458 (defvar mime-encoding-method-alist
459 '(("base64" . base64-encode-region)
460 ("quoted-printable" . quoted-printable-encode-region)
461 ;; Not standard, their use is DISCOURAGED.
462 ;; ("x-uue" . uuencode-encode-region)
463 ;; ("x-gzip64" . gzip64-encode-region)
468 "Alist of encoding vs. corresponding method to encode region.
469 Each element looks like (STRING . FUNCTION) or (STRING . nil).
470 STRING is content-transfer-encoding.
471 FUNCTION is region encoder and nil means not to encode.")
474 (defvar mime-decoding-method-alist
475 '(("base64" . base64-decode-region)
476 ("quoted-printable" . quoted-printable-decode-region)
477 ("x-uue" . uuencode-decode-region)
478 ("x-uuencode" . uuencode-decode-region)
479 ("x-gzip64" . gzip64-decode-region)
481 "Alist of encoding vs. corresponding method to decode region.
482 Each element looks like (STRING . FUNCTION).
483 STRING is content-transfer-encoding.
484 FUNCTION is region decoder.")
487 (defun mime-encode-region (start end encoding)
488 "Encode region START to END of current buffer using ENCODING.
489 ENCODING must be string. If ENCODING is found in
490 `mime-encoding-method-alist' as its key, this function encodes the
491 region by its value."
493 (list (region-beginning) (region-end)
494 (completing-read "encoding: "
495 mime-encoding-method-alist
498 (let ((f (cdr (assoc encoding mime-encoding-method-alist))))
500 (funcall f start end)
504 (defun mime-decode-region (start end encoding)
505 "Decode region START to END of current buffer using ENCODING.
506 ENCODING must be string. If ENCODING is found in
507 `mime-decoding-method-alist' as its key, this function decodes the
508 region by its value."
510 (list (region-beginning) (region-end)
511 (completing-read "encoding: "
512 mime-decoding-method-alist
515 (let ((f (cdr (assoc encoding mime-decoding-method-alist))))
517 (funcall f start end)
525 (defvar mime-string-decoding-method-alist
526 '(("base64" . base64-decode-string)
527 ("quoted-printable" . quoted-printable-decode-string)
530 ("binary" . identity)
532 "Alist of encoding vs. corresponding method to decode string.
533 Each element looks like (STRING . FUNCTION).
534 STRING is content-transfer-encoding.
535 FUNCTION is string decoder.")
538 (defun mime-decode-string (string encoding)
539 "Decode STRING using ENCODING.
540 ENCODING must be string. If ENCODING is found in
541 `mime-string-decoding-method-alist' as its key, this function decodes
542 the STRING by its value."
543 (let ((f (cdr (assoc encoding mime-string-decoding-method-alist))))
548 (mime-decode-region (point-min)(point-max) encoding)
557 (defvar mime-file-encoding-method-alist
558 '(("base64" . base64-insert-encoded-file)
559 ("quoted-printable" . quoted-printable-insert-encoded-file)
560 ;; Not standard, their use is DISCOURAGED.
561 ;; ("x-uue" . uuencode-insert-encoded-file)
562 ;; ("x-gzip64" . gzip64-insert-encoded-file)
563 ("7bit" . insert-file-contents-as-binary)
564 ("8bit" . insert-file-contents-as-binary)
565 ("binary" . insert-file-contents-as-binary)
567 "Alist of encoding vs. corresponding method to insert encoded file.
568 Each element looks like (STRING . FUNCTION).
569 STRING is content-transfer-encoding.
570 FUNCTION is function to insert encoded file.")
573 (defvar mime-file-decoding-method-alist
574 '(("base64" . base64-write-decoded-region)
575 ("quoted-printable" . quoted-printable-write-decoded-region)
576 ("x-uue" . uuencode-write-decoded-region)
577 ("x-gzip64" . gzip64-write-decoded-region)
578 ("7bit" . write-region-as-binary)
579 ("8bit" . write-region-as-binary)
580 ("binary" . write-region-as-binary)
582 "Alist of encoding vs. corresponding method to write decoded region to file.
583 Each element looks like (STRING . FUNCTION).
584 STRING is content-transfer-encoding.
585 FUNCTION is function to write decoded region to file.")
588 (defun mime-insert-encoded-file (filename encoding)
589 "Insert file FILENAME encoded by ENCODING format."
591 (list (read-file-name "Insert encoded file: ")
592 (completing-read "encoding: "
593 mime-encoding-method-alist
596 (let ((f (cdr (assoc encoding mime-file-encoding-method-alist))))
602 (defun mime-write-decoded-region (start end filename encoding)
603 "Decode and write current region encoded by ENCODING into FILENAME.
604 START and END are buffer positions."
606 (list (region-beginning) (region-end)
607 (read-file-name "Write decoded region to file: ")
608 (completing-read "encoding: "
609 mime-file-decoding-method-alist
611 (let ((f (cdr (assoc encoding mime-file-decoding-method-alist))))
613 (funcall f start end filename)
622 ;;; mel.el ends here.