2 ;;; $Id: mel-q.el,v 1.9 1995/09/09 05:14:23 morioka Exp $
8 (defconst quoted-printable-hex-chars "0123456789ABCDEF")
9 (defconst quoted-printable-octet-regexp
10 (concat "=[" quoted-printable-hex-chars
11 "][" quoted-printable-hex-chars "]"))
17 (defvar quoted-printable-external-encoder '("mmencode" "-q")
18 "*list of quoted-printable encoder program name and its arguments.")
20 (defvar quoted-printable-external-decoder '("mmencode" "-q" "-u")
21 "*list of quoted-printable decoder program name and its arguments.")
23 (defvar quoted-printable-internal-encoding-limit 10000
24 "*limit size to use internal quoted-printable encoder.
25 If size of input to encode is larger than this limit,
26 external encoder is called.")
28 (defvar quoted-printable-internal-decoding-limit nil
29 "*limit size to use internal quoted-printable decoder.
30 If size of input to decode is larger than this limit,
31 external decoder is called.")
34 ;;; @ Quoted-Printable (Q-encode) encoder/decoder
37 (defun quoted-printable-quote-char (chr)
39 (char-to-string (elt quoted-printable-hex-chars (ash chr -4)))
40 (char-to-string (elt quoted-printable-hex-chars (logand chr 15)))
44 ;;; @@ Quoted-Printable encode/decode string
47 (defun quoted-printable-encode-string (str)
51 (cond ((or (< chr 32) (< 126 chr) (eq chr ?=))
55 (concat "=\n" (quoted-printable-quote-char chr))
59 (quoted-printable-quote-char chr)
64 (concat "=\n" (char-to-string chr))
73 (defun quoted-printable-decode-string (str)
81 (cond ((<= ?a chr) (+ (- chr ?a) 10))
82 ((<= ?A chr) (+ (- chr ?A) 10))
83 ((<= ?0 chr) (- chr ?0))
87 (h (setq l (cond ((<= ?a chr) (+ (- chr ?a) 10))
88 ((<= ?A chr) (+ (- chr ?A) 10))
89 ((<= ?0 chr) (- chr ?0))
92 (char-to-string (logior (ash h 4) l))
96 (t (char-to-string chr))
101 ;;; @@ Quoted-Printable encode/decode region
104 (defun quoted-printable-internal-encode-region (beg end)
107 (narrow-to-region beg end)
108 (goto-char (point-min))
112 (beginning-of-line) (setq b (point))
113 (end-of-line) (setq e (point))
116 (setq str (buffer-substring b e))
118 (insert (quoted-printable-encode-string str))
127 (cond ((boundp 'MULE)
128 (define-program-coding-system
129 nil (car quoted-printable-external-encoder) *noconv*)
130 (define-program-coding-system
131 nil (car quoted-printable-external-decoder) *noconv*)
134 (define-program-kanji-code
135 nil (car quoted-printable-external-encoder) 0)
136 (define-program-kanji-code
137 nil (car quoted-printable-external-decoder) 0)
140 (defun quoted-printable-external-encode-region (beg end)
142 (apply (function call-process-region)
143 beg end (car quoted-printable-external-encoder)
144 t t nil (cdr quoted-printable-external-encoder))
147 (defun quoted-printable-external-decode-region (beg end)
149 (apply (function call-process-region)
150 beg end (car quoted-printable-external-decoder)
151 t t nil (cdr quoted-printable-external-decoder))
154 (defun quoted-printable-encode-region (beg end)
156 (if (and quoted-printable-internal-encoding-limit
157 (> (- end beg) quoted-printable-internal-encoding-limit))
158 (quoted-printable-external-encode-region beg end)
159 (quoted-printable-internal-encode-region beg end)
162 (defun quoted-printable-decode-region (beg end)
164 (if (and quoted-printable-internal-decoding-limit
165 (> (- end beg) quoted-printable-internal-decoding-limit))
166 (quoted-printable-external-decode-region beg end)
167 (quoted-printable-internal-decode-region beg end)
171 ;;; @ Q-encoding encode/decode string
174 (defun q-encoding-encode-string-for-text (str)
177 (cond ((eq chr 32) "_")
178 ((or (< chr 32) (< 126 chr) (eq chr ?=))
179 (quoted-printable-quote-char chr)
181 (t (char-to-string chr))
185 (defun q-encoding-encode-string-for-comment (str)
188 (cond ((eq chr 32) "_")
189 ((or (< chr 32) (< 126 chr)
190 (memq chr '(?= ?\( ?\) ?\\))
192 (quoted-printable-quote-char chr)
194 (t (char-to-string chr))
198 (defun q-encoding-encode-string-for-phrase (str)
201 (cond ((eq chr 32) "_")
202 ((or (and (<= ?A chr)(<= chr ?Z))
203 (and (<= ?a chr)(<= chr ?z))
204 (and (<= ?0 chr)(<= chr ?9))
205 (memq chr '(?! ?* ?+ ?- ?/))
209 (t (quoted-printable-quote-char chr))
213 (defun q-encoding-encode-string (str &optional mode)
214 (cond ((eq mode 'text)
215 (q-encoding-encode-string-for-text str)
218 (q-encoding-encode-string-for-comment str)
221 (q-encoding-encode-string-for-phrase str)
224 (defun q-encoding-decode-string (str)
228 (cond ((eq chr ?_) " ")
232 (q (setq h (cond ((<= ?a chr) (+ (- chr ?a) 10))
233 ((<= ?A chr) (+ (- chr ?A) 10))
234 ((<= ?0 chr) (- chr ?0))
238 (h (setq l (cond ((<= ?a chr) (+ (- chr ?a) 10))
239 ((<= ?A chr) (+ (- chr ?A) 10))
240 ((<= ?0 chr) (- chr ?0))
243 (char-to-string (logior (ash h 4) l))
247 (t (char-to-string chr))
255 (defun q-encoding-encoded-length (string &optional mode)
256 (let ((l 0)(i 0)(len (length string)) chr)
258 (setq chr (elt string i))
259 (if (string-match "[A-Za-z0-9!*+/=_---]" (char-to-string chr))