(write-region-as-binary): 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 (if running-emacs-19_29-or-later
164     ;; for MULE 2.3 based on Emacs 19.34.
165     (defun write-region-as-binary (start end filename
166                                          &optional append visit lockname)
167       "Like `write-region', q.v., but don't code conversion."
168       (let (mc-flag
169             (file-coding-system *noconv*))
170         (write-region start end filename append visit lockname)
171         ))
172   ;; for MULE 2.3 based on Emacs 19.28.
173   (defun write-region-as-binary (start end filename
174                                        &optional append visit lockname)
175     "Like `write-region', q.v., but don't code conversion."
176     (let (mc-flag
177           (file-coding-system *noconv*))
178       (write-region start end filename append visit)
179       ))
180   )
181
182
183 ;;; @ MIME charset
184 ;;;
185
186 (defun encode-mime-charset-region (start end charset)
187   "Encode the text between START and END as MIME CHARSET."
188   (let ((cs (mime-charset-to-coding-system charset)))
189     (if cs
190         (code-convert start end *internal* cs)
191       )))
192
193 (defun decode-mime-charset-region (start end charset)
194   "Decode the text between START and END as MIME CHARSET."
195   (let ((cs (mime-charset-to-coding-system charset)))
196     (if cs
197         (code-convert start end cs *internal*)
198       )))
199
200 (defun encode-mime-charset-string (string charset)
201   "Encode the STRING as MIME CHARSET."
202   (let ((cs (mime-charset-to-coding-system charset)))
203     (if cs
204         (code-convert-string string *internal* cs)
205       string)))
206
207 (defun decode-mime-charset-string (string charset)
208   "Decode the STRING which is encoded in MIME CHARSET."
209   (let ((cs (mime-charset-to-coding-system charset)))
210     (if cs
211         (decode-coding-string string cs)
212       string)))
213
214
215 ;;; @@ to coding-system
216 ;;;
217
218 (defvar mime-charset-coding-system-alist
219   '((iso-8859-1      . *ctext*)
220     (x-ctext         . *ctext*)
221     (gb2312          . *euc-china*)
222     (koi8-r          . *koi8*)
223     (iso-2022-jp-2   . *iso-2022-ss2-7*)
224     (x-iso-2022-jp-2 . *iso-2022-ss2-7*)
225     (shift_jis       . *sjis*)
226     (x-shiftjis      . *sjis*)
227     ))
228
229 (defun mime-charset-to-coding-system (charset &optional lbt)
230   (if (stringp charset)
231       (setq charset (intern (downcase charset)))
232     )
233   (let ((cs
234          (or (cdr (assq charset mime-charset-coding-system-alist))
235              (let ((cs (intern (concat "*" (symbol-name charset) "*"))))
236                (and (coding-system-p cs) cs)
237                ))))
238     (if (or (null lbt)
239             (null cs))
240         cs
241       (intern (concat (symbol-name cs) (symbol-name lbt)))
242       )))
243
244
245 ;;; @@ detection
246 ;;;
247
248 (defvar charsets-mime-charset-alist
249   (let ((alist
250          '(((lc-ascii)                                  . 'us-ascii)
251            ((lc-ascii lc-ltn1)                          . 'iso-8859-1)
252            ((lc-ascii lc-ltn2)                          . 'iso-8859-2)
253            ((lc-ascii lc-ltn3)                          . 'iso-8859-3)
254            ((lc-ascii lc-ltn4)                          . 'iso-8859-4)
255 ;;;        ((lc-ascii lc-crl)                           . 'iso-8859-5)
256            ((lc-ascii lc-crl)                           . 'koi8-r)
257            ((lc-ascii lc-arb)                           . 'iso-8859-6)
258            ((lc-ascii lc-grk)                           . 'iso-8859-7)
259            ((lc-ascii lc-hbw)                           . 'iso-8859-8)
260            ((lc-ascii lc-ltn5)                          . 'iso-8859-9)
261            ((lc-ascii lc-roman lc-jpold lc-jp)          . 'iso-2022-jp)
262            ((lc-ascii lc-kr)                            . 'euc-kr)
263            ((lc-ascii lc-cn)                            . 'gb2312)
264            ((lc-ascii lc-big5-1 lc-big5-2)              . 'big5)
265            ((lc-ascii lc-roman lc-ltn1 lc-grk
266                       lc-jpold lc-cn lc-jp lc-kr
267                       lc-jp2)                           . 'iso-2022-jp-2)
268            ((lc-ascii lc-roman lc-ltn1 lc-grk
269                       lc-jpold lc-cn lc-jp lc-kr lc-jp2
270                       lc-cns1 lc-cns2)                  . 'iso-2022-int-1)
271            ((lc-ascii lc-roman
272                       lc-ltn1 lc-ltn2 lc-crl lc-grk
273                       lc-jpold lc-cn lc-jp lc-kr lc-jp2
274                       lc-cns1 lc-cns2 lc-cns3 lc-cns4
275                       lc-cns5 lc-cns6 lc-cns7)          . 'iso-2022-int-1)
276            ))
277         dest)
278     (while alist
279       (catch 'not-found
280         (let ((pair (car alist)))
281           (setq dest
282                 (cons (mapcar (function
283                                (lambda (cs)
284                                  (if (boundp cs)
285                                      (symbol-value cs)
286                                    (throw 'not-found nil)
287                                    )))
288                               (car pair))
289                       (cdr pair)))))
290       (setq alist (cdr alist))))
291   )
292
293 (defvar default-mime-charset 'x-ctext
294   "Default value of MIME-charset.
295 It is used when MIME-charset is not specified.
296 It must be symbol.")
297
298 (defun detect-mime-charset-region (start end)
299   "Return MIME charset for region between START and END."
300   (charsets-to-mime-charset
301    (cons lc-ascii (find-charset-region start end))))
302
303
304 ;;; @ character
305 ;;;
306
307 (defalias 'char-charset 'char-leading-char)
308
309 (defalias 'char-length 'char-bytes)
310
311 (defalias 'char-columns 'char-width)
312
313
314 ;;; @ string
315 ;;;
316
317 (defalias 'string-columns 'string-width)
318
319 (defalias 'string-to-int-list 'string-to-char-list)
320
321 (or (fboundp 'truncate-string)
322 ;;; Imported from Mule-2.3
323 (defun truncate-string (str width &optional start-column)
324   "Truncate STR to fit in WIDTH columns.
325 Optional non-nil arg START-COLUMN specifies the starting column.
326 \[emu-mule.el; Mule 2.3 emulating function]"
327   (or start-column
328       (setq start-column 0))
329   (let ((max-width (string-width str))
330         (len (length str))
331         (from 0)
332         (column 0)
333         to-prev to ch)
334     (if (>= width max-width)
335         (setq width max-width))
336     (if (>= start-column width)
337         ""
338       (while (< column start-column)
339         (setq ch (aref str from)
340               column (+ column (char-width ch))
341               from (+ from (char-bytes ch))))
342       (if (< width max-width)
343           (progn
344             (setq to from)
345             (while (<= column width)
346               (setq ch (aref str to)
347                     column (+ column (char-width ch))
348                     to-prev to
349                     to (+ to (char-bytes ch))))
350             (setq to to-prev)))
351       (substring str from to))))
352 ;;;
353   )
354
355
356 ;;; @ regulation
357 ;;;
358
359 (defun regulate-latin-char (chr)
360   (cond ((and (<= ?\e$B#A\e(B chr)(<= chr ?\e$B#Z\e(B))
361          (+ (- chr ?\e$B#A\e(B) ?A)
362          )
363         ((and (<= ?\e$B#a\e(B chr)(<= chr ?\e$B#z\e(B))
364          (+ (- chr ?\e$B#a\e(B) ?a)
365          )
366         ((eq chr ?\e$B!%\e(B) ?.)
367         ((eq chr ?\e$B!$\e(B) ?,)
368         (t chr)
369         ))
370
371 (defun regulate-latin-string (str)
372   (let ((len (length str))
373         (i 0)
374         chr (dest ""))
375     (while (< i len)
376       (setq chr (sref str i))
377       (setq dest (concat dest
378                          (char-to-string (regulate-latin-char chr))))
379       (setq i (+ i (char-bytes chr)))
380       )
381     dest))
382
383
384 ;;; @ end
385 ;;;
386
387 (provide 'emu-mule)
388
389 ;;; emu-mule.el ends here