(insert-binary-file-contents): New function.
[elisp/apel.git] / emu-mule.el
1 ;;; emu-mule.el --- emu module for Mule 1.* and Mule 2.*
2
3 ;; Copyright (C) 1995,1996,1997,1998 MORIOKA Tomohiko
4
5 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
6 ;; Keywords: emulation, compatibility, Mule
7
8 ;; This file is part of emu.
9
10 ;; This program is free software; you can redistribute it and/or
11 ;; modify it under the terms of the GNU General Public License as
12 ;; published by the Free Software Foundation; either version 2, or (at
13 ;; your option) any later version.
14
15 ;; This program is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;; General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Code:
26
27 ;;; @ version specific features
28 ;;;
29
30 (cond (running-emacs-19
31        (require 'emu-19)
32        
33        ;; Suggested by SASAKI Osamu <osamu@shuugr.bekkoame.or.jp>
34        ;; (cf. [os2-emacs-ja:78])
35        (defun fontset-pixel-size (fontset)
36          (let* ((font (get-font-info
37                        (aref (cdr (get-fontset-info fontset)) 0)))
38                 (open (aref font 4)))
39            (if (= open 1)
40                (aref font 5)
41              (if (= open 0)
42                  (let ((pat (aref font 1)))
43                    (if (string-match "-[0-9]+-" pat)
44                        (string-to-number
45                         (substring
46                          pat (1+ (match-beginning 0)) (1- (match-end 0))))
47                      0)))
48              )))
49        )
50       (running-emacs-18
51        (require 'emu-18)
52        (defun make-overlay (beg end &optional buffer type))
53        (defun overlay-put (overlay prop value))
54        ))
55
56
57 ;;; @ character set
58 ;;;
59
60 (defalias 'make-char 'make-character)
61
62 (defalias 'find-non-ascii-charset-string 'find-charset-string)
63 (defalias 'find-non-ascii-charset-region 'find-charset-region)
64
65 (defalias 'charset-bytes        'char-bytes)
66 (defalias 'charset-description  'char-description)
67 (defalias 'charset-registry     'char-registry)
68 (defalias 'charset-columns      'char-width)
69 (defalias 'charset-direction    'char-direction)
70
71
72 ;;; @ coding system
73 ;;;
74
75 (defun encode-coding-region (start end coding-system)
76   "Encode the text between START and END to CODING-SYSTEM.
77 \[EMACS 20 emulating function]"
78   (code-convert-region start end *internal* coding-system)
79   )
80
81 (defun decode-coding-region (start end coding-system)
82   "Decode the text between START and END which is encoded in CODING-SYSTEM.
83 \[EMACS 20 emulating function]"
84   (code-convert-region start end coding-system *internal*)
85   )
86
87 (defun encode-coding-string (str coding-system)
88   "Encode the STRING to CODING-SYSTEM.
89 \[EMACS 20 emulating function]"
90   (code-convert-string str *internal* coding-system)
91   )
92
93 (defun decode-coding-string (str coding-system)
94   "Decode the string STR which is encoded in CODING-SYSTEM.
95 \[EMACS 20 emulating function]"
96   (let ((len (length str))
97         ret)
98     (while (and
99             (< 0 len)
100             (null
101              (setq ret
102                    (code-convert-string (substring str 0 len)
103                                         coding-system *internal*))
104              ))
105       (setq len (1- len))
106       )
107     (concat ret (substring str len))
108     ))
109
110 (defalias 'detect-coding-region 'code-detect-region)
111
112 (defalias 'set-buffer-file-coding-system 'set-file-coding-system)
113
114 (defmacro as-binary-process (&rest body)
115   (` (let (selective-display    ; Disable ^M to nl translation.
116            ;; Mule
117            mc-flag      
118            (default-process-coding-system (cons *noconv* *noconv*))
119            program-coding-system-alist)
120        (,@ body)
121        )))
122
123 (defmacro as-binary-input-file (&rest body)
124   (` (let (mc-flag
125            (file-coding-system-for-read *noconv*)
126            )
127        (,@ body)
128        )))
129
130 (defmacro as-binary-output-file (&rest body)
131   (` (let (mc-flag
132            (file-coding-system *noconv*)
133            )
134        (,@ body)
135        )))
136
137 (defalias 'set-process-input-coding-system 'set-process-coding-system)
138
139
140 ;;; @ binary access
141 ;;;
142
143 (defun insert-binary-file-contents-literally
144   (filename &optional visit beg end replace)
145   "Like `insert-file-contents-literally', q.v., but don't code conversion.
146 A buffer may be modified in several ways after reading into the buffer due
147 to advanced Emacs features, such as file-name-handlers, format decoding,
148 find-file-hooks, etc.
149   This function ensures that none of these modifications will take place."
150   (let (mc-flag
151         (file-coding-system *noconv*))
152     (insert-file-contents-literally filename visit beg end replace)
153     ))
154
155 (defun insert-binary-file-contents
156   (filename &optional visit beg end replace)
157   "Like `insert-file-contents', q.v., but don't code and format conversion."
158   (let (mc-flag
159         (file-coding-system *noconv*))
160     (insert-file-contents filename visit beg end replace)
161     ))
162
163
164 ;;; @ MIME charset
165 ;;;
166
167 (defun encode-mime-charset-region (start end charset)
168   "Encode the text between START and END as MIME CHARSET."
169   (let ((cs (mime-charset-to-coding-system charset)))
170     (if cs
171         (code-convert start end *internal* cs)
172       )))
173
174 (defun decode-mime-charset-region (start end charset)
175   "Decode the text between START and END as MIME CHARSET."
176   (let ((cs (mime-charset-to-coding-system charset)))
177     (if cs
178         (code-convert start end cs *internal*)
179       )))
180
181 (defun encode-mime-charset-string (string charset)
182   "Encode the STRING as MIME CHARSET."
183   (let ((cs (mime-charset-to-coding-system charset)))
184     (if cs
185         (code-convert-string string *internal* cs)
186       string)))
187
188 (defun decode-mime-charset-string (string charset)
189   "Decode the STRING which is encoded in MIME CHARSET."
190   (let ((cs (mime-charset-to-coding-system charset)))
191     (if cs
192         (decode-coding-string string cs)
193       string)))
194
195
196 ;;; @@ to coding-system
197 ;;;
198
199 (defvar mime-charset-coding-system-alist
200   '((iso-8859-1      . *ctext*)
201     (x-ctext         . *ctext*)
202     (gb2312          . *euc-china*)
203     (koi8-r          . *koi8*)
204     (iso-2022-jp-2   . *iso-2022-ss2-7*)
205     (x-iso-2022-jp-2 . *iso-2022-ss2-7*)
206     (shift_jis       . *sjis*)
207     (x-shiftjis      . *sjis*)
208     ))
209
210 (defun mime-charset-to-coding-system (charset &optional lbt)
211   (if (stringp charset)
212       (setq charset (intern (downcase charset)))
213     )
214   (let ((cs
215          (or (cdr (assq charset mime-charset-coding-system-alist))
216              (let ((cs (intern (concat "*" (symbol-name charset) "*"))))
217                (and (coding-system-p cs) cs)
218                ))))
219     (if (or (null lbt)
220             (null cs))
221         cs
222       (intern (concat (symbol-name cs) (symbol-name lbt)))
223       )))
224
225
226 ;;; @@ detection
227 ;;;
228
229 (defvar charsets-mime-charset-alist
230   (let ((alist
231          '(((lc-ascii)                                  . 'us-ascii)
232            ((lc-ascii lc-ltn1)                          . 'iso-8859-1)
233            ((lc-ascii lc-ltn2)                          . 'iso-8859-2)
234            ((lc-ascii lc-ltn3)                          . 'iso-8859-3)
235            ((lc-ascii lc-ltn4)                          . 'iso-8859-4)
236 ;;;        ((lc-ascii lc-crl)                           . 'iso-8859-5)
237            ((lc-ascii lc-crl)                           . 'koi8-r)
238            ((lc-ascii lc-arb)                           . 'iso-8859-6)
239            ((lc-ascii lc-grk)                           . 'iso-8859-7)
240            ((lc-ascii lc-hbw)                           . 'iso-8859-8)
241            ((lc-ascii lc-ltn5)                          . 'iso-8859-9)
242            ((lc-ascii lc-roman lc-jpold lc-jp)          . 'iso-2022-jp)
243            ((lc-ascii lc-kr)                            . 'euc-kr)
244            ((lc-ascii lc-cn)                            . 'gb2312)
245            ((lc-ascii lc-big5-1 lc-big5-2)              . 'big5)
246            ((lc-ascii lc-roman lc-ltn1 lc-grk
247                       lc-jpold lc-cn lc-jp lc-kr
248                       lc-jp2)                           . 'iso-2022-jp-2)
249            ((lc-ascii lc-roman lc-ltn1 lc-grk
250                       lc-jpold lc-cn lc-jp lc-kr lc-jp2
251                       lc-cns1 lc-cns2)                  . 'iso-2022-int-1)
252            ((lc-ascii lc-roman
253                       lc-ltn1 lc-ltn2 lc-crl lc-grk
254                       lc-jpold lc-cn lc-jp lc-kr lc-jp2
255                       lc-cns1 lc-cns2 lc-cns3 lc-cns4
256                       lc-cns5 lc-cns6 lc-cns7)          . 'iso-2022-int-1)
257            ))
258         dest)
259     (while alist
260       (catch 'not-found
261         (let ((pair (car alist)))
262           (setq dest
263                 (cons (mapcar (function
264                                (lambda (cs)
265                                  (if (boundp cs)
266                                      (symbol-value cs)
267                                    (throw 'not-found nil)
268                                    )))
269                               (car pair))
270                       (cdr pair)))))
271       (setq alist (cdr alist))))
272   )
273
274 (defvar default-mime-charset 'x-ctext
275   "Default value of MIME-charset.
276 It is used when MIME-charset is not specified.
277 It must be symbol.")
278
279 (defun detect-mime-charset-region (start end)
280   "Return MIME charset for region between START and END."
281   (charsets-to-mime-charset
282    (cons lc-ascii (find-charset-region start end))))
283
284
285 ;;; @ character
286 ;;;
287
288 (defalias 'char-charset 'char-leading-char)
289
290 (defalias 'char-length 'char-bytes)
291
292 (defalias 'char-columns 'char-width)
293
294
295 ;;; @ string
296 ;;;
297
298 (defalias 'string-columns 'string-width)
299
300 (defalias 'string-to-int-list 'string-to-char-list)
301
302 (or (fboundp 'truncate-string)
303 ;;; Imported from Mule-2.3
304 (defun truncate-string (str width &optional start-column)
305   "Truncate STR to fit in WIDTH columns.
306 Optional non-nil arg START-COLUMN specifies the starting column.
307 \[emu-mule.el; Mule 2.3 emulating function]"
308   (or start-column
309       (setq start-column 0))
310   (let ((max-width (string-width str))
311         (len (length str))
312         (from 0)
313         (column 0)
314         to-prev to ch)
315     (if (>= width max-width)
316         (setq width max-width))
317     (if (>= start-column width)
318         ""
319       (while (< column start-column)
320         (setq ch (aref str from)
321               column (+ column (char-width ch))
322               from (+ from (char-bytes ch))))
323       (if (< width max-width)
324           (progn
325             (setq to from)
326             (while (<= column width)
327               (setq ch (aref str to)
328                     column (+ column (char-width ch))
329                     to-prev to
330                     to (+ to (char-bytes ch))))
331             (setq to to-prev)))
332       (substring str from to))))
333 ;;;
334   )
335
336
337 ;;; @ regulation
338 ;;;
339
340 (defun regulate-latin-char (chr)
341   (cond ((and (<= ?\e$B#A\e(B chr)(<= chr ?\e$B#Z\e(B))
342          (+ (- chr ?\e$B#A\e(B) ?A)
343          )
344         ((and (<= ?\e$B#a\e(B chr)(<= chr ?\e$B#z\e(B))
345          (+ (- chr ?\e$B#a\e(B) ?a)
346          )
347         ((eq chr ?\e$B!%\e(B) ?.)
348         ((eq chr ?\e$B!$\e(B) ?,)
349         (t chr)
350         ))
351
352 (defun regulate-latin-string (str)
353   (let ((len (length str))
354         (i 0)
355         chr (dest ""))
356     (while (< i len)
357       (setq chr (sref str i))
358       (setq dest (concat dest
359                          (char-to-string (regulate-latin-char chr))))
360       (setq i (+ i (char-bytes chr)))
361       )
362     dest))
363
364
365 ;;; @ end
366 ;;;
367
368 (provide 'emu-mule)
369
370 ;;; emu-mule.el ends here