1;;; ind-util.el --- Transliteration and Misc. Tools for Indian Languages -*- coding: iso-2022-7bit; -*-
2
3;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
4;;   Free Software Foundation, Inc.
5
6;; Maintainer:  KAWABATA, Taichi <kawabata@m17n.org>
7;; Keywords: multilingual, Indian, Devanagari
8
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GNU Emacs; see the file COPYING.  If not, write to the
23;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24;; Boston, MA 02110-1301, USA.
25
26;;; Commentary:
27
28;; This file provides conversion between UCS and various
29;; transliteration schemes, such as ITRANS, kyoto-harvard and aiba
30;; methods.  It also provides conversion between IS 13194 and UCS.
31;; Finally, this program provides the compatibility support with
32;; old implementation of Devanagari script.
33
34;;; Code:
35
36;;; Transliteration
37
38;; The followings provide the various transliteration schemes (such as
39;; ITRANS, kyoto-harvard, and Aiba) of Indian scripts.  They are also
40;; used in quail/indian.el for typing Indian script in Emacs.
41
42(eval-and-compile
43
44(defun indian-regexp-of-hashtbl-keys (hashtbl)
45  "Returns the regular expression of hashtable keys."
46  (let (keys)
47    (maphash (lambda (key val) (push key keys)) hashtbl)
48    (regexp-opt keys)))
49
50(defvar indian-dev-base-table
51  '(
52    (;; VOWELS  (18)
53     (?$,15E(B nil) (?$,15F(B ?$,15~(B) (?$,15G(B ?$,15(B) (?$,15H(B ?$,16 (B) (?$,15I(B ?$,16!(B) (?$,15J(B ?$,16"(B)
54     (?$,15K(B ?$,16#(B) (?$,15L(B ?$,16B(B) (?$,15M(B ?$,16%(B) (?$,15N(B ?$,16&(B) (?$,15O(B ?$,16'(B) (?$,15P(B ?$,16((B)
55     (?$,15Q(B ?$,16)(B) (?$,15R(B ?$,16*(B) (?$,15S(B ?$,16+(B) (?$,15T(B ?$,16,(B) (?$,16@(B ?$,16$(B) (?$,16A(B ?$,16C(B))
56    (;; CONSONANTS (currently 42, including special cases)
57     ?$,15U(B ?$,15V(B ?$,15W(B ?$,15X(B ?$,15Y(B                  ;; GUTTRULS
58     ?$,15Z(B ?$,15[(B ?$,15\(B ?$,15](B ?$,15^(B                  ;; PALATALS
59     ?$,15_(B ?$,15`(B ?$,15a(B ?$,15b(B ?$,15c(B                  ;; CEREBRALS
60     ?$,15d(B ?$,15e(B ?$,15f(B ?$,15g(B ?$,15h(B ?$,15i(B              ;; DENTALS
61     ?$,15j(B ?$,15k(B ?$,15l(B ?$,15m(B ?$,15n(B                  ;; LABIALS
62     ?$,15o(B ?$,15p(B ?$,15q(B ?$,15r(B ?$,15s(B ?$,15t(B ?$,15u(B          ;; SEMIVOWELS
63     ?$,15v(B ?$,15w(B ?$,15x(B ?$,15y(B                    ;; SIBILANTS
64     ?$,168(B ?$,169(B ?$,16:(B ?$,16;(B ?$,16<(B ?$,16=(B ?$,16>(B ?$,16?(B      ;; NUKTAS
65     "$,15\6-5^(B" "$,15U6-5w(B")
66    (;; Misc Symbols (7)
67     ?$,15A(B ?$,15B(B ?$,15C(B ?$,15}(B ?$,16-(B ?$,160(B ?$,16D(B)
68    (;; Digits (10)
69     ?$,16F(B ?$,16G(B ?$,16H(B ?$,16I(B ?$,16J(B ?$,16K(B ?$,16L(B ?$,16M(B ?$,16N(B ?$,16O(B)
70    (;; Inscript-extra (4)  (#, $, ^, *, ])
71     "$,16-5p(B" "$,15p6-(B" "$,15d6-5p(B" "$,15v6-5p(B" "$,15|(B")))
72
73;; Punjabi is also known as Gurmukhi.
74(defvar indian-pnj-base-table
75  '(
76    (;; VOWELS
77     (?$,18%(B nil) (?$,18&(B ?$,18^(B) (?$,18'(B ?$,18_(B) (?$,18((B ?$,18`(B) (?$,18)(B ?$,18a(B) (?$,18*(B ?$,18b(B)
78     nil nil nil nil (?$,18/(B ?$,18g(B) (?$,180(B ?$,18h(B)
79     nil nil (?$,183(B ?$,18k(B) (?$,184(B ?$,18l(B) nil nil)
80    (;; CONSONANTS
81     ?$,185(B ?$,186(B ?$,187(B ?$,188(B ?$,189(B                  ;; GUTTRULS
82     ?$,18:(B ?$,18;(B ?$,18<(B ?$,18=(B ?$,18>(B                  ;; PALATALS
83     ?$,18?(B ?$,18@(B ?$,18A(B ?$,18B(B ?$,18C(B                  ;; CEREBRALS
84     ?$,18D(B ?$,18E(B ?$,18F(B ?$,18G(B ?$,18H(B nil              ;; DENTALS
85     ?$,18J(B ?$,18K(B ?$,18L(B ?$,18M(B ?$,18N(B                  ;; LABIALS
86     ?$,18O(B ?$,18P(B nil ?$,18R(B ?$,18S(B nil ?$,18U(B          ;; SEMIVOWELS
87     ?$,18V(B nil ?$,18X(B ?$,18Y(B                    ;; SIBILANTS
88     nil ?$,18y(B ?$,18z(B ?$,18{(B ?$,18|(B nil ?$,18~(B nil      ;; NUKTAS
89     "$,18<8m8>(B" nil)
90    (;; Misc Symbols (7)
91     nil ?$,18"(B nil nil ?$,18m(B nil nil) ;; ek onkar, etc.
92    (;; Digits
93     ?$,19&(B ?$,19'(B ?$,19((B ?$,19)(B ?$,19*(B ?$,19+(B ?$,19,(B ?$,19-(B ?$,19.(B ?$,19/(B)
94    (;; Inscript-extra (4)  (#, $, ^, *, ])
95     "$,18m8P(B" "$,18P8m(B" "$,18D8m8P(B" "$,18V8m8P(B" "$,18\(B")))
96
97(defvar indian-gjr-base-table
98  '(
99    (;; VOWELS
100     (?$,19E(B nil) (?$,19F(B ?$,19~(B) (?$,19G(B ?$,19(B) (?$,19H(B ?$,1: (B) (?$,19I(B ?$,1:!(B) (?$,19J(B ?$,1:"(B)
101     (?$,19K(B ?$,1:#(B) nil (?$,19M(B ?$,1:%(B) nil (?$,19O(B ?$,1:'(B) (?$,19P(B ?$,1:((B)
102     (?$,19Q(B ?$,1:)(B) nil (?$,19S(B ?$,1:+(B) (?$,19T(B ?$,1:,(B) (?$,1:@(B ?$,1:$(B) nil)
103    (;; CONSONANTS
104     ?$,19U(B ?$,19V(B ?$,19W(B ?$,19X(B ?$,19Y(B                  ;; GUTTRULS
105     ?$,19Z(B ?$,19[(B ?$,19\(B ?$,19](B ?$,19^(B                  ;; PALATALS
106     ?$,19_(B ?$,19`(B ?$,19a(B ?$,19b(B ?$,19c(B                  ;; CEREBRALS
107     ?$,19d(B ?$,19e(B ?$,19f(B ?$,19g(B ?$,19h(B nil              ;; DENTALS
108     ?$,19j(B ?$,19k(B ?$,19l(B ?$,19m(B ?$,19n(B                  ;; LABIALS
109     ?$,19o(B ?$,19p(B nil ?$,19r(B ?$,19s(B nil ?$,19u(B          ;; SEMIVOWELS
110     ?$,19v(B ?$,19w(B ?$,19x(B ?$,19y(B                    ;; SIBILANTS
111     nil nil nil nil nil nil nil nil      ;; NUKTAS
112     "$,19\:-9^(B" "$,19U:-9w(B")
113    (;; Misc Symbols (7)
114     ?$,19A(B ?$,19B(B ?$,19C(B ?$,19}(B ?$,1:-(B ?$,1:0(B nil)
115    (;; Digits
116     ?$,1:F(B ?$,1:G(B ?$,1:H(B ?$,1:I(B ?$,1:J(B ?$,1:K(B ?$,1:L(B ?$,1:M(B ?$,1:N(B ?$,1:O(B)
117    (;; Inscript-extra (4)  (#, $, ^, *, ])
118     "$,1:-9p(B" "$,19p:-(B" "$,19d:-9p(B" "$,19v:-9p(B" "$,19|(B")))
119
120(defvar indian-ori-base-table
121  '(
122    (;; VOWELS
123     (?$,1:e(B nil) (?$,1:f(B ?$,1;>(B) (?$,1:g(B ?$,1;?(B) (?$,1:h(B ?$,1;@(B) (?$,1:i(B ?$,1;A(B) (?$,1:j(B ?$,1;B(B)
124     (?$,1:k(B ?$,1;C(B) (?$,1:l(B nil) nil nil (?$,1:o(B ?$,1;G(B) (?$,1:p(B ?$,1;H(B)
125     nil nil (?$,1:s(B ?$,1;K(B) (?$,1:t(B ?$,1;L(B) (?$,1;`(B nil) (?$,1;a(B nil))
126    (;; CONSONANTS
127     ?$,1:u(B ?$,1:v(B ?$,1:w(B ?$,1:x(B ?$,1:y(B                  ;; GUTTRULS
128     ?$,1:z(B ?$,1:{(B ?$,1:|(B ?$,1:}(B ?$,1:~(B                  ;; PALATALS
129     ?$,1:(B ?$,1; (B ?$,1;!(B ?$,1;"(B ?$,1;#(B                  ;; CEREBRALS
130     ?$,1;$(B ?$,1;%(B ?$,1;&(B ?$,1;'(B ?$,1;((B nil              ;; DENTALS
131     ?$,1;*(B ?$,1;+(B ?$,1;,(B ?$,1;-(B ?$,1;.(B                  ;; LABIALS
132     ?$,1;/(B ?$,1;0(B nil ?$,1;2(B ?$,1;3(B nil nil          ;; SEMIVOWELS
133     ?$,1;6(B ?$,1;7(B ?$,1;8(B ?$,1;9(B                    ;; SIBILANTS
134     nil nil nil nil ?$,1;\(B ?$,1;](B nil ?$,1;_(B      ;; NUKTAS
135     "$,1:|;M:~(B" "$,1:u;M;7(B")
136    (;; Misc Symbols
137     ?$,1:a(B ?$,1:b(B ?$,1:c(B ?$,1;=(B ?$,1;M(B nil nil)
138    (;; Digits
139     ?$,1;f(B ?$,1;g(B ?$,1;h(B ?$,1;i(B ?$,1;j(B ?$,1;k(B ?$,1;l(B ?$,1;m(B ?$,1;n(B ?$,1;o(B)
140    (;; Inscript-extra (4)  (#, $, ^, *, ])
141     "$,1;M;0(B" "$,1;0;M(B" "$,1;$;M;0(B" "$,1;6;M;0(B" "$,1;<(B")))
142
143(defvar indian-bng-base-table
144  '(
145    (;; VOWELS
146     (?$,16e(B nil) (?$,16f(B ?$,17>(B) (?$,16g(B ?$,17?(B) (?$,16h(B ?$,17@(B) (?$,16i(B ?$,17A(B) (?$,16j(B ?$,17B(B)
147     (?$,16k(B ?$,17C(B) (?$,16l(B ?$,17b(B) nil nil (?$,16o(B ?$,17G(B) (?$,16p(B ?$,17H(B)
148     nil nil (?$,16s(B ?$,17K(B) (?$,16t(B ?$,17L(B) (?$,17`(B ?$,17D(B) (?$,17a(B ?$,17c(B))
149    (;; CONSONANTS
150     ?$,16u(B ?$,16v(B ?$,16w(B ?$,16x(B ?$,16y(B                  ;; GUTTRULS
151     ?$,16z(B ?$,16{(B ?$,16|(B ?$,16}(B ?$,16~(B                  ;; PALATALS
152     ?$,16(B ?$,17 (B ?$,17!(B ?$,17"(B ?$,17#(B                  ;; CEREBRALS
153     ?$,17$(B ?$,17%(B ?$,17&(B ?$,17'(B ?$,17((B nil              ;; DENTALS
154     ?$,17*(B ?$,17+(B ?$,17,(B ?$,17-(B ?$,17.(B                  ;; LABIALS
155     ?$,17/(B ?$,170(B nil ?$,172(B nil nil nil          ;; SEMIVOWELS
156     ?$,176(B ?$,177(B ?$,178(B ?$,179(B                    ;; SIBILANTS
157     nil nil nil nil ?$,17\(B ?$,17](B nil ?$,17_(B      ;; NUKTAS
158     "$,16|7M6~(B" "$,16u7M77(B")
159    (;; Misc Symbols
160     ?$,16a(B ?$,16b(B ?$,16c(B nil ?$,17M(B nil nil)
161    (;; Digits
162     ?$,17f(B ?$,17g(B ?$,17h(B ?$,17i(B ?$,17j(B ?$,17k(B ?$,17l(B ?$,17m(B ?$,17n(B ?$,17o(B)
163    (;; Inscript-extra (4)  (#, $, ^, *, ])
164     "$,17M70(B" "$,1707M(B" "$,17$7M70(B" "$,1767M70(B" "$,17<(B")))
165
166(defvar indian-asm-base-table
167  '(
168    (;; VOWELS
169     (?$,16e(B nil) (?$,16f(B ?$,17>(B) (?$,16g(B ?$,17?(B) (?$,16h(B ?$,17@(B) (?$,16i(B ?$,17A(B) (?$,16j(B ?$,17B(B)
170     (?$,16k(B ?$,17C(B) (?$,16l(B ?$,17b(B) nil nil (?$,16o(B ?$,17G(B) (?$,16p(B ?$,17H(B)
171     nil nil (?$,16s(B ?$,17K(B) (?$,16t(B ?$,17L(B) (?$,17`(B ?$,17D(B) (?$,17a(B ?$,17c(B))
172    (;; CONSONANTS
173     ?$,16u(B ?$,16v(B ?$,16w(B ?$,16x(B ?$,16y(B                  ;; GUTTRULS
174     ?$,16z(B ?$,16{(B ?$,16|(B ?$,16}(B ?$,16~(B                  ;; PALATALS
175     ?$,16(B ?$,17 (B ?$,17!(B ?$,17"(B ?$,17#(B                  ;; CEREBRALS
176     ?$,17$(B ?$,17%(B ?$,17&(B ?$,17'(B ?$,17((B nil              ;; DENTALS
177     ?$,17*(B ?$,17+(B ?$,17,(B ?$,17-(B ?$,17.(B                  ;; LABIALS
178     ?$,17/(B ?$,17p(B nil ?$,172(B nil nil ?$,17q(B          ;; SEMIVOWELS
179     ?$,176(B ?$,177(B ?$,178(B ?$,179(B                    ;; SIBILANTS
180     nil nil nil nil ?$,17\(B ?$,17](B nil ?$,17_(B      ;; NUKTAS
181     "$,16|7M6~(B" "$,16u7M77(B")
182    (;; Misc Symbols
183     ?$,16a(B ?$,16b(B ?$,16c(B nil ?$,17M(B nil nil)
184    (;; Digits
185     ?$,17f(B ?$,17g(B ?$,17h(B ?$,17i(B ?$,17j(B ?$,17k(B ?$,17l(B ?$,17m(B ?$,17n(B ?$,17o(B)
186    (;; Inscript-extra (4)  (#, $, ^, *, ])
187     "$,17M7p(B" "$,17p7M(B" "$,17$7M7p(B" "$,1767M7p(B" "$,17<(B")))
188
189(defvar indian-tlg-base-table
190  '(
191    (;; VOWELS
192     (?$,1=E(B nil) (?$,1=F(B ?$,1=~(B) (?$,1=G(B ?$,1=(B) (?$,1=H(B ?$,1> (B) (?$,1=I(B ?$,1>!(B) (?$,1=J(B ?$,1>"(B)
193     (?$,1=K(B ?$,1>#(B) (?$,1=L(B nil) nil (?$,1=O(B ?$,1>'(B) (?$,1=N(B ?$,1>&(B) (?$,1=P(B ?$,1>((B)
194     nil (?$,1=S(B ?$,1>+(B) (?$,1=R(B ?$,1>*(B) (?$,1=T(B ?$,1>,(B) (?$,1>@(B ?$,1>$(B) (?$,1>A(B nil))
195    (;; CONSONANTS
196     ?$,1=U(B ?$,1=V(B ?$,1=W(B ?$,1=X(B ?$,1=Y(B                  ;; GUTTRULS
197     ?$,1=Z(B ?$,1=[(B ?$,1=\(B ?$,1=](B ?$,1=^(B                  ;; PALATALS
198     ?$,1=_(B ?$,1=`(B ?$,1=a(B ?$,1=b(B ?$,1=c(B                  ;; CEREBRALS
199     ?$,1=d(B ?$,1=e(B ?$,1=f(B ?$,1=g(B ?$,1=h(B nil              ;; DENTALS
200     ?$,1=j(B ?$,1=k(B ?$,1=l(B ?$,1=m(B ?$,1=n(B                  ;; LABIALS
201     ?$,1=o(B ?$,1=p(B ?$,1=q(B ?$,1=r(B ?$,1=s(B nil ?$,1=u(B          ;; SEMIVOWELS
202     ?$,1=v(B ?$,1=w(B ?$,1=x(B ?$,1=y(B                    ;; SIBILANTS
203     nil nil nil nil nil nil nil nil      ;; NUKTAS
204     "$,1=\>-=^(B" "$,1=U>-=w(B")
205    (;; Misc Symbols
206     ?$,1=A(B ?$,1=B(B ?$,1=C(B nil ?$,1>-(B nil nil)
207    (;; Digits
208     ?$,1>F(B ?$,1>G(B ?$,1>H(B ?$,1>I(B ?$,1>J(B ?$,1>K(B ?$,1>L(B ?$,1>M(B ?$,1>N(B ?$,1>O(B)
209    (;; Inscript-extra (4)  (#, $, ^, *, ])
210     "$,1>-=p(B" "$,1=p>-(B" "$,1=d>-=p(B" "$,1=v>-=p(B" nil)))
211
212(defvar indian-knd-base-table
213  '(
214    (;; VOWELS
215     (?$,1>e(B nil) (?$,1>f(B ?$,1?>(B) (?$,1>g(B ?$,1??(B) (?$,1>h(B ?$,1?@(B) (?$,1>i(B ?$,1?A(B) (?$,1>j(B ?$,1?B(B)
216     (?$,1>k(B ?$,1?C(B) (?$,1>l(B nil) nil (?$,1>o(B ?$,1?G(B) (?$,1>n(B ?$,1?F(B) (?$,1>p(B ?$,1?H(B)
217     nil (?$,1>s(B ?$,1?K(B) (?$,1>r(B ?$,1?J(B) (?$,1>t(B ?$,1?L(B) (?$,1?`(B ?$,1?D(B) (?$,1?a(B nil))
218    (;; CONSONANTS
219     ?$,1>u(B ?$,1>v(B ?$,1>w(B ?$,1>x(B ?$,1>y(B                  ;; GUTTRULS
220     ?$,1>z(B ?$,1>{(B ?$,1>|(B ?$,1>}(B ?$,1>~(B                  ;; PALATALS
221     ?$,1>(B ?$,1? (B ?$,1?!(B ?$,1?"(B ?$,1?#(B                  ;; CEREBRALS
222     ?$,1?$(B ?$,1?%(B ?$,1?&(B ?$,1?'(B ?$,1?((B nil              ;; DENTALS
223     ?$,1?*(B ?$,1?+(B ?$,1?,(B ?$,1?-(B ?$,1?.(B                  ;; LABIALS
224     ?$,1?/(B ?$,1?0(B ?$,1?1(B ?$,1?2(B ?$,1?3(B nil ?$,1?5(B          ;; SEMIVOWELS
225     ?$,1?6(B ?$,1?7(B ?$,1?8(B ?$,1?9(B                    ;; SIBILANTS
226     nil nil nil nil nil nil ?$,1?^(B nil      ;; NUKTAS
227     "$,1>|?M>~(B" "$,1>u?M?7(B")
228    (;; Misc Symbols
229     nil ?$,1>b(B ?$,1>c(B nil ?$,1?M(B nil nil)
230    (;; Digits
231     ?$,1?f(B ?$,1?g(B ?$,1?h(B ?$,1?i(B ?$,1?j(B ?$,1?k(B ?$,1?l(B ?$,1?m(B ?$,1?n(B ?$,1?o(B)
232    (;; Inscript-extra (4)  (#, $, ^, *, ])
233     "$,1?M?0(B" "$,1?0?M(B" "$,1?$?M?0(B" "$,1?6?M?0(B" nil)))
234
235(defvar indian-mlm-base-table
236  '(
237    (;; VOWELS
238     (?$,1@%(B nil) (?$,1@&(B ?$,1@^(B) (?$,1@'(B ?$,1@_(B) (?$,1@((B ?$,1@`(B) (?$,1@)(B ?$,1@a(B) (?$,1@*(B ?$,1@b(B)
239     (?$,1@+(B ?$,1@c(B) (?$,1@,(B nil) nil (?$,1@/(B ?$,1@g(B) (?$,1@.(B ?$,1@f(B) (?$,1@0(B ?$,1@h(B)
240     nil (?$,1@3(B ?$,1@k(B) (?$,1@2(B ?$,1@j(B) (?$,1@4(B ?$,1@l(B) nil nil)
241    (;; CONSONANTS
242     ?$,1@5(B ?$,1@6(B ?$,1@7(B ?$,1@8(B ?$,1@9(B                  ;; GUTTRULS
243     ?$,1@:(B ?$,1@;(B ?$,1@<(B ?$,1@=(B ?$,1@>(B                  ;; PALATALS
244     ?$,1@?(B ?$,1@@(B ?$,1@A(B ?$,1@B(B ?$,1@C(B                  ;; CEREBRALS
245     ?$,1@D(B ?$,1@E(B ?$,1@F(B ?$,1@G(B ?$,1@H(B nil              ;; DENTALS
246     ?$,1@J(B ?$,1@K(B ?$,1@L(B ?$,1@M(B ?$,1@N(B                  ;; LABIALS
247     ?$,1@O(B ?$,1@P(B ?$,1@Q(B ?$,1@R(B ?$,1@S(B ?$,1@T(B ?$,1@U(B          ;; SEMIVOWELS
248     ?$,1@V(B ?$,1@W(B ?$,1@X(B ?$,1@Y(B                    ;; SIBILANTS
249     nil nil nil nil nil nil nil nil      ;; NUKTAS
250     "$,1@<@m@>(B" "$,1@5@m@W(B")
251    (;; Misc Symbols
252     nil ?$,1@"(B ?$,1@#(B nil ?$,1@m(B nil nil)
253    (;; Digits
254     ?$,1A&(B ?$,1A'(B ?$,1A((B ?$,1A)(B ?$,1A*(B ?$,1A+(B ?$,1A,(B ?$,1A-(B ?$,1A.(B ?$,1A/(B)
255    (;; Inscript-extra (4)  (#, $, ^, *, ])
256     "$,1@m@P(B" "$,1@P@m(B" "$,1@D@m@P(B" "$,1@V@m@P(B" nil)))
257
258(defvar indian-tml-base-table
259  '(
260    (;; VOWELS
261     (?$,1<%(B nil) (?$,1<&(B ?$,1<^(B) (?$,1<'(B ?$,1<_(B) (?$,1<((B ?$,1<`(B) (?$,1<)(B ?$,1<a(B) (?$,1<*(B ?$,1<b(B)
262     nil nil nil (?$,1</(B ?$,1<g(B) (?$,1<.(B ?$,1<f(B) (?$,1<0(B ?$,1<h(B)
263     nil (?$,1<3(B ?$,1<k(B) (?$,1<2(B ?$,1<j(B) (?$,1<4(B ?$,1<l(B) nil nil)
264    (;; CONSONANTS
265     ?$,1<5(B nil nil nil ?$,1<9(B                  ;; GUTTRULS
266     ?$,1<:(B nil ?$,1<<(B nil ?$,1<>(B                  ;; PALATALS
267     ?$,1<?(B nil nil nil ?$,1<C(B                  ;; CEREBRALS
268     ?$,1<D(B nil nil nil ?$,1<H(B ?$,1<I(B              ;; DENTALS
269     ?$,1<J(B nil nil nil ?$,1<N(B                  ;; LABIALS
270     ?$,1<O(B ?$,1<P(B ?$,1<Q(B ?$,1<R(B ?$,1<S(B ?$,1<T(B ?$,1<U(B          ;; SEMIVOWELS
271     nil ?$,1<W(B ?$,1<X(B ?$,1<Y(B                    ;; SIBILANTS
272     nil nil nil nil nil nil nil nil      ;; NUKTAS
273     "$,1<<(B" "$,1<5(B")
274    (;; Misc Symbols
275     nil ?$,1<"(B ?$,1<#(B nil ?$,1(B nil nil)
276    (;; Digits
277     nil ?$,1='(B ?$,1=((B ?$,1=)(B ?$,1=*(B ?$,1=+(B ?$,1=,(B ?$,1=-(B ?$,1=.(B ?$,1=/(B)
278    (;; Inscript-extra (4)  (#, $, ^, *, ])
279     "$,1<m<P(B" "$,1<P<m(B" "$,1<D<m<P(B" nil nil)))
280
281(defvar indian-base-table-to-language-alist
282  '((indian-dev-base-table . "Devanagari")
283    (indian-pnj-base-table . "Punjabi")
284    (indian-ori-base-table . "Oriya")
285    (indian-bng-base-table . "Bengali")
286    (indian-asm-base-table . "Assamese")
287    (indian-tlg-base-table . "Telugu")
288    (indian-knd-base-table . "Kannada")
289    (indian-mlm-base-table . "Malayalam")
290    (indian-tml-base-table . "Tamil")))
291
292(defvar indian-itrans-v5-table
293  '(;; for encode/decode
294    (;; vowels -- 18
295     "a" ("aa" "A") "i" ("ii" "I") "u" ("uu" "U")
296     ("RRi" "R^i") ("LLi" "L^i") (".c" "e.c") "E" "e" "ai"
297     "o.c"  "O"   "o"   "au"  ("RRI" "R^I") ("LLI" "L^I"))
298    (;; consonants -- 40
299     "k"   "kh"  "g"   "gh"  ("~N" "N^")
300     "ch" ("Ch" "chh") "j" "jh" ("~n" "JN")
301     "T"   "Th"  "D"   "Dh"  "N"
302     "t"   "th"  "d"   "dh"  "n"   "nh"
303     "p"   "ph"  "b"   "bh"  "m"
304     "y"   "r"   "rh"  "l"   ("L" "ld") nil  ("v" "w")
305     "sh" ("Sh" "shh") "s" "h"
306     "q" "K" "G" ("J" "z") ".D" ".Dh" "f" ("Y" "yh")
307     ("GY" "dny") "x")
308    (;; misc -- 7
309     ".N" (".n" "M") "H" ".a" ".h" ("AUM" "OM") "..")))
310
311(defvar indian-kyoto-harvard-table
312  '(;; for encode/decode
313    (;; vowel
314     "a"   ("A" "aa")  "i"   ("I" "ii")  "u"   ("U" "uu")
315     "R"   ("L" "lR")  nil   nil   "e"   "ai"
316     nil   nil   "o"   "au"  ("q" "RR" "Q")   ("E" "LL" "lRR"))
317    (;; consonant
318     "k"   "kh"  "g"   "gh"  "G"
319     "c"   "ch"  "j"   "jh"  "J"
320     "T"   "Th"  "D"   "Dh"  "N"
321     "t"   "th"  "d"   "dh"  "n"   nil
322     "p"   "ph"  "b"   "bh"  "m"
323     "y"   "r"   nil   "l"   "L"   nil   "v"
324     ("z" "Z")   "S"   "s"   "h"
325     nil   nil   nil   nil   nil   nil   nil   nil
326     nil   nil)
327    (;; misc
328     nil   "M"   "H"   "'"   nil   "." nil)))
329
330(defvar indian-harvard-table
331  '(;; for encode/decode
332    (;; vowel
333     "a"   ("A" "aa")  "i"   ("I" "ii")  "u"   ("U" "uu")
334     "R"   ("L" "lR")  nil   nil   "e"   "ai"
335     nil   nil   "o"   "au"  ("RR" "q" "Q")   ("LL" "E" "lRR"))
336    (;; consonant
337     "k"   "kh"  "g"   "gh"  "G"
338     "c"   "ch"  "j"   "jh"  "J"
339     "T"   "Th"  "D"   "Dh"  "N"
340     "t"   "th"  "d"   "dh"  "n"   nil
341     "p"   "ph"  "b"   "bh"  "m"
342     "y"   "r"   nil   "l"   "L"   nil   "v"
343     ("z" "Z")   "S"   "s"   "h"
344     nil   nil   nil   nil   nil   nil   nil   nil
345     nil   nil)
346    (;; misc
347     nil   "M"   "H"   "'"   nil   "." nil)))
348
349(defvar indian-tokyo-table
350  '(;; for encode/decode
351    (;; vowel
352     "a"   ("A" "aa")  "i"   ("I" "ii")  "u"   ("U" "uu")
353     "R"   ("L" "lR")  nil   nil   "e"   "ai"
354     nil   nil   "o"   "au"  ("Q" "RR" "q")   ("E" "LL" "lRR"))
355    (;; consonant
356     "k"   "kh"  "g"   "gh"  "G"
357     "c"   "ch"  "j"   "jh"  "J"
358     "T"   "Th"  "D"   "Dh"  "N"
359     "t"   "th"  "d"   "dh"  "n"   nil
360     "p"   "ph"  "b"   "bh"  "m"
361     "y"   "r"   nil   "l"   "L"   nil   "v"
362     ("Z" "z")   "S"   "s"   "h"
363     nil   nil   nil   nil   nil   nil   nil   nil
364     nil   nil)
365    (;; misc
366     nil   "M"   "H"   "'"   nil   "." nil)))
367
368(defvar indian-aiba-table
369  '(;; for encode/decode
370    (;; vowel
371     "a"   "aa"  "i"   "ii"  "u"   "uu"
372     ".r"  ".l"   nil   nil  "e"   "ai"
373     nil   nil   "o"   "au"  "~r"  "~l")
374    (;; consonant
375     "k"   "kh"  "g"   "gh"  "^n"
376     "c"   "ch"  "j"   "jh"  "~n"
377     ".t"  ".th" ".d"  ".dh" ".n"
378     "t"   "th"  "d"   "dh"  "n"   nil
379     "p"   "ph"  "b"   "bh"  "m"
380     "y"   "r"   nil   "l"   nil  nil  "v"
381     "^s"  ".s"  "s"   "h"
382     nil   nil   nil   nil   nil   nil   nil   nil
383     nil   nil)
384    (;; misc
385     nil   ".m"  ".h"  "'"   nil   "." nil)))
386
387(defun mapthread (function seq1 &rest seqrest)
388  "Apply FUNCTION to each element of SEQ1 and return result list.
389If there are several SEQRESTs, FUNCTION is called with that many
390arguments, with all possible combinations of these multiple SEQUENCES.
391Thus, if SEQ1 contains 3 elements and SEQ2 contains 5 elements, then
392FUNCTION will be called 15 times."
393  (if seqrest
394      (mapcar
395       (lambda (x)
396         (apply
397          'mapthread
398          `(lambda (&rest y) (apply ',function x y))
399          seqrest))
400       seq1)
401  (mapcar function seq1)))
402
403(defun indian--puthash-char (char trans-char hashtbls)
404  (let ((encode-hash (car hashtbls))  ;; char -> trans
405	(decode-hash (cdr hashtbls))  ;; trans -> char
406	)
407    ;; char -- nil / char / string (/ list of vowel & matra)
408    ;; trans-char -- nil / string / list of strings
409    (when (and char trans-char)
410      (if (stringp trans-char) (setq trans-char (list trans-char)))
411      (if (char-valid-p char) (setq char (char-to-string char)))
412      (puthash char (car trans-char) encode-hash)
413      (dolist (trans trans-char)
414	 (puthash trans char decode-hash)))))
415
416(defun indian--map (f l1 l2)
417  (while l1
418    (funcall f (pop l1) (pop l2))))
419
420(defun indian--puthash-v (v trans-v hashtbls)
421  (indian--map
422   (lambda (v trans-v)
423     (indian--puthash-char (car v) trans-v hashtbls))
424   v trans-v))
425
426(defun indian--puthash-c (c trans-c halant hashtbls)
427  (indian--map
428   (lambda (c trans-c)
429     (if (char-valid-p c) (setq c (char-to-string c)))
430     (indian--puthash-char (concat c halant) trans-c hashtbls))
431   c trans-c))
432
433(defun indian--puthash-m (m trans-m hashtbls)
434  (indian--map
435   (lambda (m trans-m)
436     (indian--puthash-char m trans-m hashtbls))
437   m trans-m))
438
439(defun indian--puthash-cv (c trans-c v trans-v hashtbls)
440  (indian--map
441   (lambda (c trans-c)
442     (indian--map
443      (lambda (v trans-v)
444	(when (and c trans-c  v trans-v)
445	  (if (char-valid-p c) (setq c (char-to-string c)))
446	  (setq v (if (char-valid-p (cadr v)) (char-to-string (cadr v)) ""))
447	  (if (stringp trans-c) (setq trans-c (list trans-c)))
448	  (if (stringp trans-v) (setq trans-v (list trans-v)))
449	  (indian--puthash-char
450	   (concat c v)
451	   (apply 'append
452		  (mapthread 'concat trans-c trans-v))
453	   hashtbls)))
454      v trans-v))
455   c trans-c))
456
457(defun indian-make-hash (table trans-table)
458  "Indian Transliteration Hash for decode/encode"
459  (let* ((encode-hash (make-hash-table :test 'equal))
460	 (decode-hash (make-hash-table :test 'equal))
461	 (hashtbls (cons encode-hash decode-hash))
462	 (vowels     (elt table 0))
463	 (consonants (elt table 1))
464	 (misc       (elt table 2))
465	 (digits     (elt table 3))
466	 (halant     (char-to-string (elt misc  4)))
467	 (trans-vowels     (elt trans-table 0))
468	 (trans-consonants (elt trans-table 1))
469	 (trans-misc       (elt trans-table 2))
470	 (trans-digits  '("0" "1" "2" "3" "4" "5" "6" "7" "8" "9")))
471    (indian--puthash-v vowels trans-vowels hashtbls)
472    (indian--puthash-c consonants trans-consonants halant hashtbls)
473    (indian--puthash-cv consonants trans-consonants
474			      vowels trans-vowels hashtbls)
475    (indian--puthash-m misc trans-misc hashtbls)
476    (indian--puthash-m digits trans-digits hashtbls)
477    hashtbls))
478
479(defvar indian-dev-itrans-v5-hash
480  (indian-make-hash indian-dev-base-table
481			  indian-itrans-v5-table))
482(defvar indian-dev-kyoto-harvard-hash
483  (indian-make-hash indian-dev-base-table
484			  indian-kyoto-harvard-table))
485(defvar indian-dev-aiba-hash
486  (indian-make-hash indian-dev-base-table
487			  indian-aiba-table))
488
489(defvar indian-pnj-itrans-v5-hash
490  (indian-make-hash indian-pnj-base-table
491			  indian-itrans-v5-table))
492
493(defvar indian-gjr-itrans-v5-hash
494  (indian-make-hash indian-gjr-base-table
495			  indian-itrans-v5-table))
496
497(defvar indian-ori-itrans-v5-hash
498  (indian-make-hash indian-ori-base-table
499			  indian-itrans-v5-table))
500
501(defvar indian-bng-itrans-v5-hash
502  (indian-make-hash indian-bng-base-table
503			  indian-itrans-v5-table))
504
505(defvar indian-asm-itrans-v5-hash
506  (indian-make-hash indian-asm-base-table
507			  indian-itrans-v5-table))
508
509(defvar indian-tlg-itrans-v5-hash
510  (indian-make-hash indian-tlg-base-table
511			  indian-itrans-v5-table))
512
513(defvar indian-knd-itrans-v5-hash
514  (indian-make-hash indian-knd-base-table
515			  indian-itrans-v5-table))
516
517(defvar indian-mlm-itrans-v5-hash
518  (indian-make-hash indian-mlm-base-table
519			  indian-itrans-v5-table))
520
521(defvar indian-tml-itrans-v5-hash
522  (indian-make-hash indian-tml-base-table
523			  indian-itrans-v5-table))
524)
525
526(defmacro indian-translate-region (from to hashtable encode-p)
527  `(save-excursion
528     (save-restriction
529       (let ((regexp ,(indian-regexp-of-hashtbl-keys
530		       (if encode-p (car (eval hashtable))
531			 (cdr (eval hashtable))))))
532	 (narrow-to-region from to)
533	 (goto-char (point-min))
534	 (while (re-search-forward regexp nil t)
535	   (let ((matchstr (gethash (match-string 0)
536				    (if ,encode-p
537					(car ,hashtable)
538				      (cdr ,hashtable)))))
539	     (if matchstr (replace-match matchstr))))))))
540
541;;;
542
543(defun indian-dev-itrans-v5-encode-region (from to)
544  (interactive "r")
545  (indian-translate-region
546   from to indian-dev-itrans-v5-hash t))
547
548(defun indian-dev-itrans-v5-decode-region (from to)
549  (interactive "r")
550  (indian-translate-region
551   from to indian-dev-itrans-v5-hash nil))
552
553(defun indian-dev-kyoto-harvard-encode-region (from to)
554  (interactive "r")
555  (indian-translate-region
556   from to indian-dev-kyoto-harvard-hash t))
557
558(defun indian-dev-kyoto-harvard-decode-region (from to)
559  (interactive "r")
560  (indian-translate-region
561   from to indian-dev-kyoto-harvard-hash nil))
562
563(defun indian-dev-aiba-encode-region (from to)
564  (interactive "r")
565  (indian-translate-region
566   from to indian-dev-aiba-hash t))
567
568(defun indian-dev-aiba-decode-region (from to)
569  (interactive "r")
570  (indian-translate-region
571   from to indian-dev-aiba-hash nil))
572
573
574
575
576;;; IS 13194 utilities
577
578;; The followings provide conversion between IS 13194 (ISCII) and UCS.
579
580(defvar ucs-devanagari-to-is13194-alist
581  '(;;Unicode vs IS13194  ;; only Devanagari is supported now.
582    (?\x0900 . "[U+0900]")
583    (?\x0901 . "(5!(B")
584    (?\x0902 . "(5"(B")
585    (?\x0903 . "(5#(B")
586    (?\x0904 . "[U+0904]")
587    (?\x0905 . "(5$(B")
588    (?\x0906 . "(5%(B")
589    (?\x0907 . "(5&(B")
590    (?\x0908 . "(5'(B")
591    (?\x0909 . "(5((B")
592    (?\x090a . "(5)(B")
593    (?\x090b . "(5*(B")
594    (?\x090c . "(5&i(B")
595    (?\x090d . "(5.(B")
596    (?\x090e . "(5+(B")
597    (?\x090f . "(5,(B")
598    (?\x0910 . "(5-(B")
599    (?\x0911 . "(52(B")
600    (?\x0912 . "(5/(B")
601    (?\x0913 . "(50(B")
602    (?\x0914 . "(51(B")
603    (?\x0915 . "(53(B")
604    (?\x0916 . "(54(B")
605    (?\x0917 . "(55(B")
606    (?\x0918 . "(56(B")
607    (?\x0919 . "(57(B")
608    (?\x091a . "(58(B")
609    (?\x091b . "(59(B")
610    (?\x091c . "(5:(B")
611    (?\x091d . "(5;(B")
612    (?\x091e . "(5<(B")
613    (?\x091f . "(5=(B")
614    (?\x0920 . "(5>(B")
615    (?\x0921 . "(5?(B")
616    (?\x0922 . "(5@(B")
617    (?\x0923 . "(5A(B")
618    (?\x0924 . "(5B(B")
619    (?\x0925 . "(5C(B")
620    (?\x0926 . "(5D(B")
621    (?\x0927 . "(5E(B")
622    (?\x0928 . "(5F(B")
623    (?\x0929 . "(5G(B")
624    (?\x092a . "(5H(B")
625    (?\x092b . "(5I(B")
626    (?\x092c . "(5J(B")
627    (?\x092d . "(5K(B")
628    (?\x092e . "(5L(B")
629    (?\x092f . "(5M(B")
630    (?\x0930 . "(5O(B")
631    (?\x0931 . "(5P(B")
632    (?\x0932 . "(5Q(B")
633    (?\x0933 . "(5R(B")
634    (?\x0934 . "(5S(B")
635    (?\x0935 . "(5T(B")
636    (?\x0936 . "(5U(B")
637    (?\x0937 . "(5V(B")
638    (?\x0938 . "(5W(B")
639    (?\x0939 . "(5X(B")
640    (?\x093a . "[U+093a]")
641    (?\x093b . "[U+093b]")
642    (?\x093c . "(5i(B")
643    (?\x093d . "(5ji(B")
644    (?\x093e . "(5Z(B")
645    (?\x093f . "(5[(B")
646    (?\x0940 . "(5\(B")
647    (?\x0941 . "(5](B")
648    (?\x0942 . "(5^(B")
649    (?\x0943 . "(5_(B")
650    (?\x0944 . "(5_i(B")
651    (?\x0945 . "(5c(B")
652    (?\x0946 . "(5`(B")
653    (?\x0947 . "(5a(B")
654    (?\x0948 . "(5b(B")
655    (?\x0949 . "(5g(B")
656    (?\x094a . "(5d(B")
657    (?\x094b . "(5e(B")
658    (?\x094c . "(5f(B")
659    (?\x094d . "(5h(B")
660    (?\x094e . "[U+094e]")
661    (?\x094f . "[U+094f]")
662    (?\x0950 . "(5!i(B")
663    (?\x0951 . "(5p5(B")
664    (?\x0952 . "(5p8(B")
665    (?\x0953 . "[DEVANAGARI GRAVE ACCENT]")
666    (?\x0954 . "[DEVANAGARI ACUTE ACCENT]")
667    (?\x0955 . "[U+0955]")
668    (?\x0956 . "[U+0956]")
669    (?\x0957 . "[U+0957]")
670    (?\x0958 . "(53i(B")
671    (?\x0959 . "(54i(B")
672    (?\x095a . "(55i(B")
673    (?\x095b . "(5:i(B")
674    (?\x095c . "(5?i(B")
675    (?\x095d . "(5@i(B")
676    (?\x095e . "(5Ii(B")
677    (?\x095f . "(5N(B")
678    (?\x0960 . "(5*i(B")
679    (?\x0961 . "(5'i(B")
680    (?\x0962 . "(5[i(B")
681    (?\x0963 . "(5ei(B")
682    (?\x0964 . "(5j(B")
683    (?\x0965 . "(5jj(B")
684    (?\x0966 . "(5q(B")
685    (?\x0967 . "(5r(B")
686    (?\x0968 . "(5s(B")
687    (?\x0969 . "(5t(B")
688    (?\x096a . "(5u(B")
689    (?\x096b . "(5v(B")
690    (?\x096c . "(5w(B")
691    (?\x096d . "(5x(B")
692    (?\x096e . "(5y(B")
693    (?\x096f . "(5z(B")
694    (?\x0970 . "[U+0970]")
695    (?\x0971 . "[U+0971]")
696    (?\x0972 . "[U+0972]")
697    (?\x0973 . "[U+0973]")
698    (?\x0974 . "[U+0974]")
699    (?\x0975 . "[U+0975]")
700    (?\x0976 . "[U+0976]")
701    (?\x0977 . "[U+0977]")
702    (?\x0978 . "[U+0978]")
703    (?\x0979 . "[U+0979]")
704    (?\x097a . "[U+097a]")
705    (?\x097b . "[U+097b]")
706    (?\x097c . "[U+097c]")
707    (?\x097d . "[U+097d]")
708    (?\x097e . "[U+097e]")
709    (?\x097f . "[U+097f]")))
710
711(defvar ucs-bengali-to-is13194-alist nil)
712(defvar ucs-assamese-to-is13194-alist nil)
713(defvar ucs-gurmukhi-to-is13194-alist nil)
714(defvar ucs-gujarati-to-is13194-alist nil)
715(defvar ucs-oriya-to-is13194-alist nil)
716(defvar ucs-tamil-to-is13194-alist nil)
717(defvar ucs-telugu-to-is13194-alist nil)
718(defvar ucs-malayalam-to-is13194-alist nil)
719(defvar ucs-kannada-to-is13194-alist nil)
720
721(defvar is13194-default-repartory 'devanagari)
722
723(defvar is13194-repertory-to-ucs-script
724  `((DEF ?\x40 ,is13194-default-repartory)
725    (RMN ?\x41 ,is13194-default-repartory)
726    (DEV ?\x42 devanagari)
727    (BNG ?\x43 bengali)
728    (TML ?\x44 tamil)
729    (TLG ?\x45 telugu)
730    (ASM ?\x46 bengali)
731    (ORI ?\x47 oriya)
732    (KND ?\x48 kannada)
733    (MLM ?\x49 malayalam)
734    (GJR ?\x4a gujarati)
735    (PNJ ?\x4b gurmukhi)))
736
737;; for guiding find-variable function.
738(defvar is13194-to-ucs-devanagari-hashtbl nil)
739(defvar is13194-to-ucs-devanagari-regexp nil)
740(defvar is13194-to-ucs-bengali-hashtbl nil)
741(defvar is13194-to-ucs-bengali-regexp nil)
742(defvar is13194-to-ucs-assamese-hashtbl nil)
743(defvar is13194-to-ucs-assamese-regexp nil)
744(defvar is13194-to-ucs-gurmukhi-hashtbl nil)
745(defvar is13194-to-ucs-gurmukhi-regexp nil)
746(defvar is13194-to-ucs-gujarati-hashtbl nil)
747(defvar is13194-to-ucs-gujarati-regexp nil)
748(defvar is13194-to-ucs-oriya-hashtbl nil)
749(defvar is13194-to-ucs-oriya-regexp nil)
750(defvar is13194-to-ucs-tamil-hashtbl nil)
751(defvar is13194-to-ucs-tamil-regexp nil)
752(defvar is13194-to-ucs-telugu-hashtbl nil)
753(defvar is13194-to-ucs-telugu-regexp nil)
754(defvar is13194-to-ucs-malayalam-hashtbl nil)
755(defvar is13194-to-ucs-malayalam-regexp nil)
756(defvar is13194-to-ucs-kannada-hashtbl nil)
757(defvar is13194-to-ucs-kannada-regexp nil)
758
759(mapc
760 (function (lambda (script)
761   (let ((hashtable (intern (concat "is13194-to-ucs-"
762                                    (symbol-name script) "-hashtbl" )))
763         (regexp    (intern (concat "is13194-to-ucs-"
764                                    (symbol-name script) "-regexp"))))
765     (set hashtable (make-hash-table :test 'equal :size 128))
766     (mapc
767      (function (lambda (x)
768        (put-char-code-property (decode-char 'ucs (car x))
769                                'script script)
770        (put-char-code-property (decode-char 'ucs (car x))
771                                'iscii (cdr x))
772        (puthash (cdr x) (char-to-string (decode-char 'ucs (car x)))
773                 (eval hashtable))))
774      (eval (intern (concat "ucs-" (symbol-name script)
775                            "-to-is13194-alist"))))
776     (set regexp (indian-regexp-of-hashtbl-keys (eval hashtable))))))
777 '(devanagari bengali assamese gurmukhi gujarati
778   oriya tamil telugu malayalam kannada))
779
780(defvar ucs-to-is13194-regexp
781  ;; only Devanagari is supported now.
782  (concat "[" (char-to-string (decode-char 'ucs #x0900))
783          "-" (char-to-string (decode-char 'ucs #x097f)) "]")
784  "Regexp that matches to conversion")
785
786(defun ucs-to-iscii-region (from to)
787  "Converts the indian UCS characters in the region to ISCII.
788Returns new end position."
789  (interactive "r")
790  ;; only Devanagari is supported now.
791  (save-excursion
792    (save-restriction
793      (narrow-to-region from to)
794      (goto-char (point-min))
795      (let* ((current-repertory is13194-default-repartory))
796        (while (re-search-forward ucs-to-is13194-regexp nil t)
797          (replace-match
798           (get-char-code-property (string-to-char (match-string 0))
799                                   'iscii))))
800      (point-max))))
801
802(defun iscii-to-ucs-region (from to)
803  "Converts the ISCII characters in the region to UCS.
804Returns new end position."
805  (interactive "r")
806  ;; only Devanagari is supported now.
807  (save-excursion
808    (save-restriction
809      (narrow-to-region from to)
810      (goto-char (point-min))
811      (let* ((current-repertory is13194-default-repartory)
812             (current-hashtable
813              (intern (concat "is13194-to-ucs-"
814                              (symbol-name current-repertory) "-hashtbl")))
815             (current-regexp
816              (intern (concat "is13194-to-ucs-"
817                              (symbol-name current-repertory) "-regexp"))))
818        (while (re-search-forward (eval current-regexp) nil t)
819          (replace-match
820           (gethash (match-string 0) (eval current-hashtable) ""))))
821      (point-max))))
822
823;;;###autoload
824(defun indian-compose-region (from to)
825  "Compose the region according to `composition-function-table'."
826  (interactive "r")
827  (save-excursion
828    (save-restriction
829      (let ((pos from) chars (max to))
830        (narrow-to-region from to)
831        (while (< pos max)
832          (setq chars (compose-chars-after pos))
833          (if chars (setq pos (+ pos chars)) (setq pos (1+ pos))))))))
834
835;;;###autoload
836(defun indian-compose-string (string)
837  (with-temp-buffer
838    (insert string)
839    (indian-compose-region (point-min) (point-max))
840    (buffer-string)))
841
842;;;###autoload
843(defun in-is13194-post-read-conversion (len)
844  (let ((pos (point)) endpos)
845    (setq endpos (iscii-to-ucs-region pos (+ pos len)))
846    (indian-compose-region pos endpos)
847    (- endpos pos)))
848
849;;;###autoload
850(defun in-is13194-pre-write-conversion (from to)
851  (let ((buf (current-buffer)))
852    (set-buffer (generate-new-buffer " *temp*"))
853    (if (stringp from)
854	(insert from)
855      (insert-buffer-substring buf from to))
856    (ucs-to-iscii-region (point-min) (point-max))
857    nil))
858
859
860
861
862;;; Backward Compatibility support programs
863
864;; The followings provides the conversion from old-implementation of
865;; Emacs Devanagari script to UCS.
866
867(defconst indian-2-colum-to-ucs
868  '(
869  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
870  ;;2120   $(5!!!"!#!$!%!&!'!(!)!*!+!,!-!.!/(B
871  ("$(5!!(B" . "$,15A(B")
872  ("$(5!"(B" . "$,15B(B")
873  ("$(5!#(B" . "$,15C(B")
874  ("$(5!$(B" . "$,15E(B")
875  ("$(5!%(B" . "$,15F(B")
876  ("$(5!&(B" . "$,15G(B")
877  ("$(5!'(B" . "$,15H(B")
878  ("$(5!((B" . "$,15I(B")
879  ("$(5!)(B" . "$,15J(B")
880  ("$(5!*(B" . "$,15K(B")
881  ("$(5!*"p(B" . "$,15p6#(B")
882  ("$(5!+(B" . "$,15N(B")
883  ("$(5!,(B" . "$,15O(B")
884  ("$(5!-(B" . "$,15P(B")
885  ("$(5!.(B" . "$,15M(B")
886  ("$(5!/(B" . "$,15R(B")
887  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
888  ;;2130 $(5!0!1!2!3!4!5!6!7!8!9!:!;!<!=!>!?(B
889  ("$(5!0(B" . "$,15S(B")
890  ("$(5!1(B" . "$,15T(B")
891  ("$(5!2(B" . "$,15Q(B")
892  ("$(5!3(B" . "$,15U(B")
893  ("$(5!4(B" . "$,15V(B")
894  ("$(5!5(B" . "$,15W(B")
895  ("$(5!6(B" . "$,15X(B")
896  ("$(5!7(B" . "$,15Y(B")
897  ("$(5!8(B" . "$,15Z(B")
898  ("$(5!9(B" . "$,15[(B")
899  ("$(5!:(B" . "$,15\(B")
900  ("$(5!;(B" . "$,15](B")
901  ("$(5!<(B" . "$,15^(B")
902  ("$(5!=(B" . "$,15_(B")
903  ("$(5!>(B" . "$,15`(B")
904  ("$(5!?(B" . "$,15a(B")
905  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
906  ;;2140 $(5!@!A!B!C!D!E!F!G!H!I!J!K!L!M!N!O(B
907  ("$(5!@(B" . "$,15b(B")
908  ("$(5!A(B" . "$,15c(B")
909  ("$(5!B(B" . "$,15d(B")
910  ("$(5!C(B" . "$,15e(B")
911  ("$(5!D(B" . "$,15f(B")
912  ("$(5!E(B" . "$,15g(B")
913  ("$(5!F(B" . "$,15h(B")
914  ("$(5!G(B" . "$,15i(B")
915  ("$(5!H(B" . "$,15j(B")
916  ("$(5!I(B" . "$,15k(B")
917  ("$(5!J(B" . "$,15l(B")
918  ("$(5!K(B" . "$,15m(B")
919  ("$(5!L(B" . "$,15n(B")
920  ("$(5!M(B" . "$,15o(B")
921  ("$(5!N(B" . "$,16?(B")
922  ("$(5!O(B" . "$,15p(B")
923  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
924  ;;2150 $(5!P!Q!R!S!T!U!V!W!X!Y!Z![!\!]!^!_(B
925  ("$(5!P(B" . "$,15q(B")
926  ("$(5!Q(B" . "$,15r(B")
927  ("$(5!R(B" . "$,15s(B")
928  ("$(5!S(B" . "$,15t(B")
929  ("$(5!T(B" . "$,15u(B")
930  ("$(5!U(B" . "$,15v(B")
931  ("$(5!V(B" . "$,15w(B")
932  ("$(5!W(B" . "$,15x(B")
933  ("$(5!X(B" . "$,15y(B")
934  ("$(5!Z(B" . "$,15~(B")
935  ("$(5![(B" . "$,15(B")
936  ("$(5!\(B" . "$,16 (B")
937  ("$(5!](B" . "$,16!(B")
938  ("$(5!^(B" . "$,16"(B")
939  ("$(5!_(B" . "$,16#(B")
940  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
941  ;;2160 $(5!`!a!b!c!d!e!f!g!h!i!j!k!l!m!n!o(B
942  ("$(5!`(B" . "$,16&(B")
943  ("$(5!a(B" . "$,16'(B")
944  ("$(5!b(B" . "$,16((B")
945  ("$(5!c(B" . "$,16%(B")
946  ("$(5!d(B" . "$,16*(B")
947  ("$(5!e(B" . "$,16+(B")
948  ("$(5!f(B" . "$,16,(B")
949  ("$(5!g(B" . "$,16)(B")
950  ("$(5!h(B" . "$,16-(B")
951  ("$(5!i(B" . "$,15|(B")
952  ("$(5!j(B" . "$,16D(B")
953  ("$(5!j!j(B" . "$,16E(B")
954  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
955  ;;2170 $(5!p!q!r!s!t!u!v!w!x!y!z!{!|!}!~(B
956  ("$(5!q(B" . "$,16F(B")
957  ("$(5!r(B" . "$,16G(B")
958  ("$(5!s(B" . "$,16H(B")
959  ("$(5!t(B" . "$,16I(B")
960  ("$(5!u(B" . "$,16J(B")
961  ("$(5!v(B" . "$,16K(B")
962  ("$(5!w(B" . "$,16L(B")
963  ("$(5!x(B" . "$,16M(B")
964  ("$(5!y(B" . "$,16N(B")
965  ("$(5!z(B" . "$,16O(B")
966  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
967  ;;2220   $(5"!"""#"$"%"&"'"(")"*"+","-"."/(B
968  ("$(5"!(B" . "$,16;6-5p(B")
969  ("$(5""(B" . "$,16>6-5p(B")
970  ("$(5"#(B" . "$,15U6-5p(B")
971  ("$(5"$(B" . "$,15W6-5p(B")
972  ("$(5"%(B" . "$,15d6-5p(B")
973  ("$(5"&(B" . "$,15j6-5p(B")
974  ("$(5"'(B" . "$,15k6-5p(B")
975  ("$(5")(B" . "$,15v6-5p(B")
976  ("$(5",(B" . "$,15p6!(B")
977  ("$(5"-(B" . "$,15p6"(B")
978  ("$(5".(B" . "$,15q6!(B")
979  ("$(5"/(B" . "$,15q6"(B")
980  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
981  ;;2230 $(5"0"1"2"3"4"5"6"7"8"9":";"<"=">"?(B
982  ("$(5"3(B" . "$,15U6-(B")
983  ("$(5"4(B" . "$,15V6-(B")
984  ("$(5"5(B" . "$,15W6-(B")
985  ("$(5"6(B" . "$,15X6-(B")
986  ("$(5"8(B" . "$,15Z6-(B")
987  ("$(5"8"q(B" . "$,15Z6-5p6-(B")
988  ("$(5":(B" . "$,15\6-(B")
989  ("$(5";(B" . "$,15]6-(B")
990  ("$(5"<(B" . "$,15^6-(B")
991  ("$(5"<(B" . "$,15^6-(B")
992  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
993  ;;2240 $(5"@"A"B"C"D"E"F"G"H"I"J"K"L"M"N"O(B
994  ("$(5"A(B" . "$,15c6-(B")
995  ("$(5"B(B" . "$,15d6-(B")
996  ("$(5"C(B" . "$,15e6-(B")
997  ("$(5"E(B" . "$,15g6-(B")
998  ("$(5"F(B" . "$,15h6-(B")
999  ("$(5"G(B" . "$,15i6-(B")
1000  ("$(5"H(B" . "$,15j6-(B")
1001  ("$(5"I(B" . "$,15k6-(B")
1002  ("$(5"J(B" . "$,15l6-(B")
1003  ("$(5"J(B" . "$,15l6-(B")
1004  ("$(5"K(B" . "$,15m6-(B")
1005  ("$(5"L(B" . "$,15n6-(B")
1006  ("$(5"M(B" . "$,15o6-(B")
1007  ("$(5"N(B" . "$,16?6-(B")
1008  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1009  ;;2250 $(5"P"Q"R"S"T"U"V"W"X"Y"Z"["\"]"^"_(B
1010  ("$(5"Q(B" . "$,15r6-(B")
1011  ("$(5"R(B" . "$,15s6-(B")
1012  ("$(5"S(B" . "$,15t6-(B")
1013  ("$(5"T(B" . "$,15u6-(B")
1014  ("$(5"U(B" . "$,15v6-(B")
1015  ("$(5"V(B" . "$,15w6-(B")
1016  ("$(5"W(B" . "$,15x6-(B")
1017  ("$(5"](B" . "$,16-5o(B")
1018  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1019  ;;2260 $(5"`"a"b"c"d"e"f"g"h"i"j"k"l"m"n"o(B
1020  ("$(5"`(B" . "$,15W6-5p6-(B")
1021  ("$(5"a(B" . "$,15X6-5h6-(B")
1022  ("$(5"c(B" . "$,15d6-5d6-(B")
1023  ("$(5"d(B" . "$,15d6-5p6-(B")
1024  ("$(5"e(B" . "$,15g6-5h6-(B")
1025  ("$(5"f(B" . "$,15g6-5p6-(B")
1026  ("$(5"g(B" . "$,15j6-5d6-(B")
1027  ("$(5"h(B" . "$,15v6-5Z6-(B")
1028  ("$(5"i(B" . "$,15v6-5p6-(B")
1029  ("$(5"j(B" . "$,15v6-5u6-(B")
1030  ("$(5"k(B" . "$,15h6-5h6-(B")
1031  ("$(5"l(B" . "$,15U6-5w6-(B")
1032  ("$(5"m(B" . "$,15\6-5^6-(B")
1033  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1034  ;;2270 $(5"p"q"r"s"t"u"v"w"x"y"z"{"|"}"~(B
1035  ("$(5"p(B" . "$,15p6-(B")
1036  ("$(5"q(B" . "$,16-5p(B")
1037  ("$(5"r(B" . "$,16-5p(B")
1038  ("$(5"s(B" . "$,1686-(B")
1039  ("$(5"t(B" . "$,1696-(B")
1040  ("$(5"u(B" . "$,16:6-(B")
1041  ("$(5"y(B" . "$,16>6-(B")
1042  ("$(5"z(B" . "$,16;6-(B")
1043  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1044  ;;2320   $(5#!#"###$#%#&#'#(#)#*#+#,#-#.#/(B
1045  ("$(5#!(B" . "$,160(B")
1046  ("$(5#&(B" . "$,15L(B")
1047  ("$(5#&"p(B" . "$,15p6$(B")
1048  ("$(5#'(B" . "$,16A(B")
1049  ("$(5#'"p(B" . "$,15p6C(B")
1050  ("$(5#*(B" . "$,16@(B")
1051  ("$(5#*"p(B" . "$,15p6B(B")
1052  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1053  ;;2330 $(5#0#1#2#3#4#5#6#7#8#9#:#;#<#=#>#?(B
1054  ("$(5#3(B" . "$,168(B")
1055  ("$(5#4(B" . "$,169(B")
1056  ("$(5#5(B" . "$,16:(B")
1057  ("$(5#:(B" . "$,16;(B")
1058  ("$(5#?(B" . "$,16<(B")
1059  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1060  ;;2340 $(5#@#A#B#C#D#E#F#G#H#I#J#K#L#M#N#O(B
1061  ("$(5#@(B" . "$,16=(B")
1062  ("$(5#I(B" . "$,16>(B")
1063  ("$(5#J(B" . "$,15}(B")
1064  ("$(5#K(B" . "$,16$(B")
1065  ("$(5#L(B" . "$,16B(B")
1066  ("$(5#M(B" . "$,16C(B")
1067  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1068  ;;2350 $(5#P#Q#R#S#T#U#V#W#X#Y#Z#[#\#]#^#_(B
1069  ("$(5#P(B" . "$,15n6-5h(B")
1070  ("$(5#Q(B" . "$,15n6-5r(B")
1071  ("$(5#R(B" . "$,15y6#(B")
1072  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1073  ;;2360 $(5#`#a#b#c#d#e#f#g#h#i#j#k#l#m#n#o(B
1074  ("$(5#`(B" . "$,15r6-5r(B")
1075  ("$(5#a(B" . "$,15u6-5h(B")
1076  ("$(5#b(B" . "$,15u6-5u(B")
1077  ("$(5#c(B" . "$,15v6-5Z(B")
1078  ("$(5#d(B" . "$,15v6-5h(B")
1079  ("$(5#e(B" . "$,15v6-5l(B")
1080  ("$(5#f(B" . "$,15v6-5r(B")
1081  ("$(5#g(B" . "$,15v6-5u(B")
1082  ("$(5#h(B" . "$,15w6-5_6-5p6-5o(B")
1083  ("$(5#i(B" . "$,15w6-5_6-5o(B")
1084  ("$(5#j(B" . "$,15w6-5_6-5u(B")
1085  ("$(5#k(B" . "$,15w6-5_(B")
1086  ("$(5#l(B" . "$,15w6-5`(B")
1087  ("$(5#m(B" . "$,15x6-5h(B")
1088  ("$(5#n(B" . "$,15x6-5p(B")
1089  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1090  ;;2370 $(5#p#q#r#s#t#u#v#w#x#y#z#{#|#}#~(B
1091  ("$(5#p(B" . "$,15y6-5c(B")
1092  ("$(5#q(B" . "$,15y6-5h(B")
1093  ("$(5#r(B" . "$,15y6-5n(B")
1094  ("$(5#s(B" . "$,15y6-5o(B")
1095  ("$(5#t(B" . "$,15y6-5p(B")
1096  ("$(5#u(B" . "$,15y6-5r(B")
1097  ("$(5#v(B" . "$,15y6-5u(B")
1098  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1099  ;;2420   $(5$!$"$#$$$%$&$'$($)$*$+$,$-$.$/(B
1100  ("$(5$!(B" . "$,15U6-5d6-5p6-5o(B")
1101  ("$(5$"(B" . "$,15U6-5d6-5u(B")
1102  ("$(5$#(B" . "$,15U6-5d6-5o(B")
1103  ("$(5$$(B" . "$,15U6-5h6-5o(B")
1104  ("$(5$%(B" . "$,15U6-5p6-5o(B")
1105  ("$(5$&(B" . "$,15U6-5u6-5o(B")
1106  ("$(5$'(B" . "$,15U6-5U(B")
1107  ("$(5$((B" . "$,15U6-5d(B")
1108  ("$(5$)(B" . "$,15U6-5h(B")
1109  ("$(5$*(B" . "$,15U6-5n(B")
1110  ("$(5$+(B" . "$,15U6-5o(B")
1111  ("$(5$,(B" . "$,15U6-5r(B")
1112  ("$(5$-(B" . "$,15U6-5u(B")
1113  ("$(5$.(B" . "$,15U6-5w(B")
1114  ("$(5$/(B" . "$,15X6-5h(B")
1115  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1116  ;;2430 $(5$0$1$2$3$4$5$6$7$8$9$:$;$<$=$>$?(B
1117  ("$(5$0(B" . "$,15Y6-5U6-5d6-5o(B")
1118  ("$(5$1(B" . "$,15Y6-5U6-5w6-5u(B")
1119  ("$(5$2(B" . "$,15Y6-5U6-5d(B")
1120  ("$(5$3(B" . "$,15Y6-5U6-5w(B")
1121  ("$(5$4(B" . "$,15Y6-5X6-5p(B")
1122  ("$(5$5(B" . "$,15Y6-5U6-5o(B")
1123  ("$(5$6(B" . "$,15Y6-5V6-5o(B")
1124  ("$(5$7(B" . "$,15Y6-5W6-5o(B")
1125  ("$(5$8(B" . "$,15Y6-5X6-5o(B")
1126  ("$(5$9(B" . "$,15Y6-5U(B")
1127  ("$(5$:(B" . "$,15Y6-5V(B")
1128  ("$(5$;(B" . "$,15Y6-5W(B")
1129  ("$(5$<(B" . "$,15Y6-5X(B")
1130  ("$(5$=(B" . "$,15Y6-5Y(B")
1131  ("$(5$>(B" . "$,15Y6-5h(B")
1132  ("$(5$?(B" . "$,15Y6-5n(B")
1133  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1134  ;;2440 $(5$@$A$B$C$D$E$F$G$H$I$J$K$L$M$N$O(B
1135  ("$(5$@(B" . "$,15Y6-5o(B")
1136  ("$(5$A(B" . "$,15Z6-5Z(B")
1137  ("$(5$B(B" . "$,15Z6-5^(B")
1138  ("$(5$C(B" . "$,15[6-5o(B")
1139  ("$(5$D(B" . "$,15\6-5p(B")
1140  ("$(5$E(B" . "$,15\6-5^(B")
1141  ("$(5$F(B" . "$,15^6-5Z(B")
1142  ("$(5$G(B" . "$,15^6-5\(B")
1143  ("$(5$H(B" . "$,15_6-5U(B")
1144  ("$(5$I(B" . "$,15_6-5_(B")
1145  ("$(5$J(B" . "$,15_6-5`(B")
1146  ("$(5$K(B" . "$,15_6-5o(B")
1147  ("$(5$L(B" . "$,15`6-5o(B")
1148  ("$(5$M(B" . "$,15a6-5W6-5o(B")
1149  ("$(5$N(B" . "$,15a6-5X6-5p(B")
1150  ("$(5$O(B" . "$,15a6-5p6-5o(B")
1151  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1152  ;;2450 $(5$P$Q$R$S$T$U$V$W$X$Y$Z$[$\$]$^$_(B
1153  ("$(5$P(B" . "$,15a6-5W(B")
1154  ("$(5$Q(B" . "$,15a6-5X(B")
1155  ("$(5$R(B" . "$,15a6-5a(B")
1156  ("$(5$S(B" . "$,15a6-5n(B")
1157  ("$(5$T(B" . "$,15a6-5o(B")
1158  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1159  ;;2460 $(5$`$a$b$c$d$e$f$g$h$i$j$k$l$m$n$o(B
1160  ("$(5$`(B" . "$,15b6-5o(B")
1161  ("$(5$a(B" . "$,15d6-5d(B")
1162  ("$(5$b(B" . "$,15d6-5h(B")
1163  ("$(5$c(B" . "$,15f6-5f6-5o(B")
1164  ("$(5$d(B" . "$,15f6-5g6-5o(B")
1165  ("$(5$e(B" . "$,15f6-5m6-5o(B")
1166  ("$(5$f(B" . "$,15f6-5p6-5o(B")
1167  ("$(5$g(B" . "$,15f6-5u6-5o(B")
1168  ("$(5$h(B" . "$,15f6-5W6-5p(B")
1169  ("$(5$i(B" . "$,15f6-5X6-5p(B")
1170  ("$(5$j(B" . "$,15f6-5f6-5u(B")
1171  ("$(5$k(B" . "$,15f6-5g6-5u(B")
1172  ("$(5$l(B" . "$,15f6-5W(B")
1173  ("$(5$m(B" . "$,15f6-5X(B")
1174  ("$(5$n(B" . "$,15f6-5f(B")
1175  ("$(5$o(B" . "$,15f6-5g(B")
1176  ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
1177  ;;2470 $(5$p$q$r$s$t$u$v$w$x$y$z${$|$}$~(B
1178  ("$(5$p(B" . "$,15f6-5h(B")
1179  ("$(5$q(B" . "$,15f6-5l(B")
1180  ("$(5$r(B" . "$,15f6-5m(B")
1181  ("$(5$s(B" . "$,15f6-5n(B")
1182  ("$(5$t(B" . "$,15f6-5o(B")
1183  ("$(5$u(B" . "$,15f6-5u(B")
1184  ("$(5$v(B" . "$,15g6-5h(B")
1185  ("$(5$w(B" . "$,15h6-5h(B")
1186  ("$(5$x(B" . "$,15j6-5d(B")
1187  ("$(5$y(B" . "$,15j6-5h(B")
1188  ("$(5$z(B" . "$,15j6-5r(B")
1189  ("$(5${(B" . "$,15l6-5h(B")
1190  ("$(5$|(B" . "$,15l6-5l(B")
1191  ("$(5$}(B" . "$,15l6-5u(B")
1192  ("$(5$~(B" . "$,15m6-5h(B")))
1193
1194(defconst indian-2-column-to-ucs-regexp
1195  "$(5!j!j(B\\|$(5"8"q(B\\|[$(5#&#'!*#*(B]$(5"p(B\\|[$(5!!(B-$(5$~(B]")
1196
1197(put 'indian-2-column-to-ucs-chartable 'char-table-extra-slots 1)
1198(defconst indian-2-column-to-ucs-chartable
1199  (let ((table (make-char-table 'indian-2-column-to-ucs-chartable))
1200        (alist nil))
1201    (dolist (elt indian-2-colum-to-ucs)
1202      (if (= (length (car elt)) 1)
1203          (aset table (aref (car elt) 0) (cdr elt))
1204        (setq alist (cons elt alist))))
1205    (set-char-table-extra-slot table 0 alist)
1206    table))
1207
1208(defun indian-2-column-to-ucs-region (from to)
1209  "Convert old Emacs Devanagari characters to UCS."
1210  (interactive "r")
1211  (save-excursion
1212    (save-restriction
1213      (let ((pos from)
1214            (alist (char-table-extra-slot indian-2-column-to-ucs-chartable 0)))
1215        (narrow-to-region from to)
1216        (decompose-region from to)
1217        (goto-char (point-min))
1218        (while (re-search-forward indian-2-column-to-ucs-regexp nil t)
1219          (let ((len (- (match-end 0) (match-beginning 0)))
1220                subst)
1221            (if (= len 1)
1222                (setq subst (aref indian-2-column-to-ucs-chartable
1223				  (char-after (match-beginning 0))))
1224              (setq subst (cdr (assoc (match-string 0) alist))))
1225            (replace-match (if subst subst "?"))))
1226        (indian-compose-region (point-min) (point-max))))))
1227
1228;;;###autoload
1229(defun indian-glyph-char (index &optional script)
1230  "Return character of charset `indian-glyph' made from glyph index INDEX.
1231The variable `indian-default-script' specifies the script of the glyph.
1232Optional argument SCRIPT, if non-nil, overrides `indian-default-script'.
1233See also the function `indian-char-glyph'."
1234  (or script
1235      (setq script indian-default-script))
1236  (let ((offset (get script 'indian-glyph-code-offset)))
1237    (or (integerp offset)
1238	(error "Invalid script name: %s" script))
1239    (or (and (>= index 0) (< index 256))
1240	(error "Invalid glyph index: %d" index))
1241    (setq index (+ offset index))
1242    (make-char 'indian-glyph (+ (/ index 96) 32) (+ (% index 96) 32))))
1243
1244(defvar indian-glyph-max-char
1245  (indian-glyph-char
1246   255 (aref indian-script-table (1- (length indian-script-table))))
1247  "The maximum valid code of characters in the charset `indian-glyph'.")
1248
1249;;;###autoload
1250(defun indian-char-glyph (char)
1251  "Return information about the glyph code for CHAR of `indian-glyph' charset.
1252The value is (INDEX . SCRIPT), where INDEX is the glyph index
1253in the font that Indian script name SCRIPT specifies.
1254See also the function `indian-glyph-char'."
1255  (let ((split (split-char char))
1256	code)
1257    (or (eq (car split) 'indian-glyph)
1258	(error "Charset of `%c' is not indian-glyph" char))
1259    (or (<= char indian-glyph-max-char)
1260	(error "Invalid indian-glyph char: %d" char))
1261    (setq code (+ (* (- (nth 1 split) 32) 96) (nth 2 split) -32))
1262    (cons (% code 256) (aref indian-script-table (/ code 256)))))
1263
1264(provide 'ind-util)
1265
1266;;; arch-tag: 59aacd71-46c2-4cb3-bb26-e12bbad55545
1267;;; ind-util.el ends here
1268