comparison lisp/mel/mel-q.el @ 4:b82b59fe008d r19-15b3

Import from CVS: tag r19-15b3
author cvs
date Mon, 13 Aug 2007 08:46:56 +0200
parents
children 4b173ad71786
comparison
equal deleted inserted replaced
3:30df88044ec6 4:b82b59fe008d
1 ;;; mel-q.el: Quoted-Printable and Q-encoding encoder/decoder for GNU Emacs
2
3 ;; Copyright (C) 1995,1996 Free Software Foundation, Inc.
4
5 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
6 ;; Created: 1995/6/25
7 ;; Version: $Id: mel-q.el,v 1.1.1.1 1996/12/18 03:55:30 steve Exp $
8 ;; Keywords: MIME, Quoted-Printable, Q-encoding
9
10 ;; This file is part of MEL (MIME Encoding Library).
11
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.
16
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.
21
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.
26
27 ;;; Code:
28
29 (require 'emu)
30
31
32 ;;; @ constants
33 ;;;
34
35 (defconst quoted-printable-hex-chars "0123456789ABCDEF")
36 (defconst quoted-printable-octet-regexp
37 (concat "=[" quoted-printable-hex-chars
38 "][" quoted-printable-hex-chars "]"))
39
40
41 ;;; @ variables
42 ;;;
43
44 (defvar quoted-printable-external-encoder '("mmencode" "-q")
45 "*list of quoted-printable encoder program name and its arguments.")
46
47 (defvar quoted-printable-external-decoder '("mmencode" "-q" "-u")
48 "*list of quoted-printable decoder program name and its arguments.")
49
50 (defvar quoted-printable-internal-encoding-limit 10000
51 "*limit size to use internal quoted-printable encoder.
52 If size of input to encode is larger than this limit,
53 external encoder is called.")
54
55 (defvar quoted-printable-internal-decoding-limit nil
56 "*limit size to use internal quoted-printable decoder.
57 If size of input to decode is larger than this limit,
58 external decoder is called.")
59
60
61 ;;; @ Quoted-Printable (Q-encode) encoder/decoder
62 ;;;
63
64 (defun byte-to-hex-string (num)
65 (concat (char-to-string (elt quoted-printable-hex-chars (ash num -4)))
66 (char-to-string (elt quoted-printable-hex-chars (logand num 15)))
67 ))
68
69 (defun quoted-printable-quote-char (chr)
70 (concat "="
71 (char-to-string (elt quoted-printable-hex-chars (ash chr -4)))
72 (char-to-string (elt quoted-printable-hex-chars (logand chr 15)))
73 ))
74
75
76 ;;; @@ Quoted-Printable encoder/decoder for string
77 ;;;
78
79 (defun quoted-printable-encode-string (str)
80 (let ((i 0))
81 (mapconcat (function
82 (lambda (chr)
83 (cond ((eq chr ?\n)
84 (setq i 0)
85 "\n")
86 ((or (< chr 32) (< 126 chr) (eq chr ?=))
87 (if (>= i 73)
88 (progn
89 (setq i 3)
90 (concat "=\n" (quoted-printable-quote-char chr))
91 )
92 (progn
93 (setq i (+ i 3))
94 (quoted-printable-quote-char chr)
95 )))
96 (t (if (>= i 75)
97 (progn
98 (setq i 1)
99 (concat "=\n" (char-to-string chr))
100 )
101 (progn
102 (setq i (1+ i))
103 (char-to-string chr)
104 )))
105 )))
106 str "")))
107
108 (defun quoted-printable-decode-string (str)
109 (let (q h l)
110 (mapconcat (function
111 (lambda (chr)
112 (cond ((eq chr ?=)
113 (setq q t)
114 "")
115 (q (setq h
116 (cond ((<= ?a chr) (+ (- chr ?a) 10))
117 ((<= ?A chr) (+ (- chr ?A) 10))
118 ((<= ?0 chr) (- chr ?0))
119 ))
120 (setq q nil)
121 "")
122 (h (setq l (cond ((<= ?a chr) (+ (- chr ?a) 10))
123 ((<= ?A chr) (+ (- chr ?A) 10))
124 ((<= ?0 chr) (- chr ?0))
125 ))
126 (prog1
127 (char-to-string (logior (ash h 4) l))
128 (setq h nil)
129 )
130 )
131 (t (char-to-string chr))
132 )))
133 str "")))
134
135
136 ;;; @@ Quoted-Printable encoder/decoder for region
137 ;;;
138
139 (defun quoted-printable-internal-encode-region (beg end)
140 (save-excursion
141 (save-restriction
142 (narrow-to-region beg end)
143 (let ((str (buffer-substring beg end)))
144 (delete-region beg end)
145 (insert (quoted-printable-encode-string str))
146 )
147 (or (bolp)
148 (insert "=\n")
149 )
150 )))
151
152 (defun quoted-printable-internal-decode-region (beg end)
153 (save-excursion
154 (save-restriction
155 (narrow-to-region beg end)
156 (goto-char (point-min))
157 (while (re-search-forward "=\n" nil t)
158 (replace-match "")
159 )
160 (goto-char (point-min))
161 (let (b e str)
162 (while (re-search-forward quoted-printable-octet-regexp nil t)
163 (setq b (match-beginning 0))
164 (setq e (match-end 0))
165 (setq str (buffer-substring b e))
166 (delete-region b e)
167 (insert (quoted-printable-decode-string str))
168 ))
169 )))
170
171 (defun quoted-printable-external-encode-region (beg end)
172 (save-excursion
173 (save-restriction
174 (narrow-to-region beg end)
175 (as-binary-process
176 (apply (function call-process-region)
177 beg end (car quoted-printable-external-encoder)
178 t t nil (cdr quoted-printable-external-encoder))
179 )
180 ;; for OS/2
181 ;; regularize line break code
182 (goto-char (point-min))
183 (while (re-search-forward "\r$" nil t)
184 (replace-match "")
185 )
186 )))
187
188 (defun quoted-printable-external-decode-region (beg end)
189 (save-excursion
190 (as-binary-process
191 (apply (function call-process-region)
192 beg end (car quoted-printable-external-decoder)
193 t t nil (cdr quoted-printable-external-decoder))
194 )))
195
196 (defun quoted-printable-encode-region (beg end)
197 (interactive "r")
198 (if (and quoted-printable-internal-encoding-limit
199 (> (- end beg) quoted-printable-internal-encoding-limit))
200 (quoted-printable-external-encode-region beg end)
201 (quoted-printable-internal-encode-region beg end)
202 ))
203
204 (defun quoted-printable-decode-region (beg end)
205 (interactive "r")
206 (if (and quoted-printable-internal-decoding-limit
207 (> (- end beg) quoted-printable-internal-decoding-limit))
208 (quoted-printable-external-decode-region beg end)
209 (quoted-printable-internal-decode-region beg end)
210 ))
211
212
213 ;;; @@ Quoted-Printable encoder/decoder for file
214 ;;;
215
216 (defun quoted-printable-insert-encoded-file (filename)
217 (interactive (list (read-file-name "Insert encoded file: ")))
218 (apply (function call-process) (car quoted-printable-external-encoder)
219 filename t nil (cdr quoted-printable-external-encoder))
220 )
221
222
223 ;;; @ Q-encoding encode/decode string
224 ;;;
225
226 (defconst q-encoding-special-chars-alist
227 '((text ?= ?? ?_)
228 (comment ?= ?? ?_ ?\( ?\) ?\\)
229 (phrase ?= ?? ?_ ?\( ?\) ?\\ ?\" ?# ?$ ?% ?& ?' ?, ?. ?/
230 ?: ?\; ?< ?> ?@ ?\[ ?\] ?^ ?` ?{ ?| ?} ?~)
231 ))
232
233 (defun q-encoding-encode-string (str &optional mode)
234 (let ((specials (cdr (or (assq mode q-encoding-special-chars-alist)
235 (assq 'phrase q-encoding-special-chars-alist)
236 ))))
237 (mapconcat (function
238 (lambda (chr)
239 (cond ((eq chr 32) "_")
240 ((or (< chr 32) (< 126 chr)
241 (memq chr specials)
242 )
243 (quoted-printable-quote-char chr)
244 )
245 (t
246 (char-to-string chr)
247 ))
248 ))
249 str "")
250 ))
251
252 (defun q-encoding-decode-string (str)
253 (let (q h l)
254 (mapconcat (function
255 (lambda (chr)
256 (cond ((eq chr ?_) " ")
257 ((eq chr ?=)
258 (setq q t)
259 "")
260 (q (setq h (cond ((<= ?a chr) (+ (- chr ?a) 10))
261 ((<= ?A chr) (+ (- chr ?A) 10))
262 ((<= ?0 chr) (- chr ?0))
263 ))
264 (setq q nil)
265 "")
266 (h (setq l (cond ((<= ?a chr) (+ (- chr ?a) 10))
267 ((<= ?A chr) (+ (- chr ?A) 10))
268 ((<= ?0 chr) (- chr ?0))
269 ))
270 (prog1
271 (char-to-string (logior (ash h 4) l))
272 (setq h nil)
273 )
274 )
275 (t (char-to-string chr))
276 )))
277 str "")))
278
279
280 ;;; @@ etc
281 ;;;
282
283 (defun q-encoding-printable-char-p (chr mode)
284 (and (not (memq chr '(?= ?? ?_)))
285 (<= ?\ chr)(<= chr ?~)
286 (cond ((eq mode 'text) t)
287 ((eq mode 'comment)
288 (not (memq chr '(?\( ?\) ?\\)))
289 )
290 (t
291 (string-match "[A-Za-z0-9!*+/=_---]" (char-to-string chr))
292 ))))
293
294 (defun q-encoding-encoded-length (string &optional mode)
295 (let ((l 0)(i 0)(len (length string)) chr)
296 (while (< i len)
297 (setq chr (elt string i))
298 (if (q-encoding-printable-char-p chr mode)
299 (setq l (+ l 1))
300 (setq l (+ l 3))
301 )
302 (setq i (+ i 1)) )
303 l))
304
305
306 ;;; @ end
307 ;;;
308
309 (provide 'mel-q)
310
311 ;;; mel-q.el ends here