]> code.delx.au - gnu-emacs/blob - lisp/language/knd-util.el
(gud-comint-buffer): Move forward to stop byte compiler warnings.
[gnu-emacs] / lisp / language / knd-util.el
1 ;;; knd-util.el --- Support for composing Kannada characters
2
3 ;; Copyright (C) 2003 Free Software Foundation, Inc.
4
5 ;; Maintainer: Maintainer: CHOWKSEY, Kailash C. <klchxbec@m-net.arbornet.org>
6 ;; Keywords: multilingual, Kannada
7
8 ;; This file is part of GNU Emacs.
9
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU 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., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
24
25 ;; Created: Jul. 14. 2003
26
27 ;;; Commentary:
28
29 ;; This file provides character(Unicode) to glyph(CDAC) conversion and
30 ;; composition of Kannada script characters.
31
32 ;;; Code:
33
34 ;;;###autoload
35
36 ;; Kannada Composable Pattern
37 ;; C .. Consonants
38 ;; V .. Vowel
39 ;; H .. Virama
40 ;; M .. Matra
41 ;; V .. Vowel
42 ;; (N .. Zerowidth Non Joiner)
43 ;; (J .. Zerowidth Joiner. )
44 ;; 1. vowel
45 ;; V(A)?
46 ;; 2. syllable : maximum of 5 consecutive consonants. (e.g. kartsnya)
47 ;; ((CH)?(CH)?(CH)?CH)?C(H|M?)?
48
49 (defconst kannada-consonant
50 "[\e$,1>u\e(B-\e$,1?9\e(B]")
51
52 (defconst kannada-consonant-needs-twirl
53 "[\e$,1>u>w\e(B-\e$,1>{>}\e(B-\e$,1>~? \e(B-\e$,1?"?$\e(B-\e$,1?+?-?0?3\e(B-\e$,1?9\e(B]\\(\e$,1?M\e(B[\e$,1>u\e(B-\e$,1?9\e(B]\\)*[\e$,1?A?B?C?D>b\e(B]?$")
54
55 (defconst kannada-composable-pattern
56 (concat
57 "\\([\e$,1>b\e(B-\e$,1>t?`>l\e(B]\\)\\|[\e$,1>c\e(B]"
58 "\\|\\("
59 "\\(?:\\(?:[\e$,1>u\e(B-\e$,1?9\e(B]\e$,1?M\e(B\\)?\\(?:[\e$,1>u\e(B-\e$,1?9\e(B]\e$,1?M\e(B\\)?\\(?:[\e$,1>u\e(B-\e$,1?9\e(B]\e$,1?M\e(B\\)?[\e$,1>u\e(B-\e$,1?9\e(B]\e$,1?M\e(B\\)?"
60 "[\e$,1>u\e(B-\e$,1?9\e(B]\\(?:\e$,1?M\e(B\\|[\e$,1?>\e(B-\e$,1?M?U?C\e(B]?\\)?"
61 "\\)")
62 "Regexp matching a composable sequence of Kannada characters.")
63
64 ;;;###autoload
65 (defun kannada-compose-region (from to)
66 (interactive "r")
67 (save-excursion
68 (save-restriction
69 (narrow-to-region from to)
70 (goto-char (point-min))
71 (while (re-search-forward kannada-composable-pattern nil t)
72 (kannada-compose-syllable-region (match-beginning 0)
73 (match-end 0))))))
74 ;;;###autoload
75 (defun kannada-compose-string (string)
76 (with-temp-buffer
77 (insert (decompose-string string))
78 (kannada-compose-region (point-min) (point-max))
79 (buffer-string)))
80
81 ;;;###autoload
82 (defun kannada-post-read-conversion (len)
83 (save-excursion
84 (save-restriction
85 (let ((buffer-modified-p (buffer-modified-p)))
86 (narrow-to-region (point) (+ (point) len))
87 (kannada-compose-region (point-min) (point-max))
88 (set-buffer-modified-p buffer-modified-p)
89 (- (point-max) (point-min))))))
90
91 (defun kannada-range (from to)
92 "Make the list of the integers of range FROM to TO."
93 (let (result)
94 (while (<= from to) (setq result (cons to result) to (1- to))) result))
95
96 (defun kannada-regexp-of-hashtbl-keys (hashtbl)
97 "Return a regular expression that matches all keys in hashtable HASHTBL."
98 (let ((max-specpdl-size 1000))
99 (regexp-opt
100 (sort
101 (let (dummy)
102 (maphash (function (lambda (key val) (setq dummy (cons key dummy)))) hashtbl)
103 dummy)
104 (function (lambda (x y) (> (length x) (length y))))))))
105
106 (defun kannada-regexp-of-hashtbl-vals (hashtbl)
107 "Return a regular expression that matches all values in hashtable HASHTBL."
108 (let ((max-specpdl-size 1000))
109 (regexp-opt
110 (sort
111 (let (dummy)
112 (maphash (function (lambda (key val) (setq dummy (cons val dummy)))) hashtbl)
113 dummy)
114 (function (lambda (x y) (> (length x) (length y))))))))
115
116 (defun kannada-composition-function (from to pattern &optional string)
117 "Compose Kannada characters in REGION, or STRING if specified.
118 Assume that the REGION or STRING must fully match the composable
119 PATTERN regexp."
120 (if string (kannada-compose-syllable-string string)
121 (kannada-compose-syllable-region from to))
122 (- to from))
123
124 ;; Register a function to compose Kannada characters.
125 (mapc
126 (function (lambda (ucs)
127 (aset composition-function-table (decode-char 'ucs ucs)
128 (list (cons kannada-composable-pattern
129 'kannada-composition-function)))))
130 (kannada-range #x0c80 #x0cff))
131
132 ;; Notes on conversion steps.
133
134 ;; 1. chars to glyphs
135 ;;
136 ;; Rules will not be applied to the virama appeared at the end of the
137 ;; text. Also, the preceding/following "r" will be treated as special case.
138
139 ;; 2. glyphs reordering.
140 ;;
141 ;; The glyphs are split by virama, and each glyph groups are
142 ;; re-ordered in the following order.
143 ;;
144 ;; Note that `consonant-glyph' mentioned here does not contain the
145 ;; vertical bar (right modifier) attached at the right of the
146 ;; consonant.
147 ;;
148 ;; If the glyph-group contains right modifier,
149 ;; (1) consonant-glyphs/vowels
150 ;; (2) spacing
151 ;; (3) right modifier (may be matra)
152 ;; (4) top matra
153 ;; (5) preceding "r"
154 ;; (7) following "r"
155 ;; (8) bottom matra or virama.
156 ;;
157 ;; Otherwise,
158 ;; (1) consonant-glyph/vowels, with nukta sign
159 ;; (3) left matra
160 ;; (4) top matra
161 ;; (5) preceding "r"
162 ;; (7) following "r"
163 ;; (8) bottom matra or virama.
164 ;; (2) spacing
165
166 ;; 3. glyph to glyph
167 ;;
168 ;; For better display, some glyph display would be tuned.
169
170 ;; 4. Composition.
171 ;;
172 ;; left modifiers will be attached at the left.
173 ;; others will be attached right.
174
175 ;; Problem::
176 ;; Can we generalize this methods to other Indian scripts?
177
178 (defvar knd-char-glyph
179 '(("\e$,1>e\e(B" . "\e$,43@\e(B")
180 ("\e$,1>f\e(B" . "\e$,43A\e(B")
181 ("\e$,1?>\e(B" . "\e$,44{\e(B")
182 ("\e$,1>g\e(B" . "\e$,43B\e(B")
183 ("\e$,1??\e(B" . nil)
184 ("\e$,1>h\e(B" . "\e$,43C\e(B")
185 ("\e$,1?@\e(B" . nil)
186 ("\e$,1>i\e(B" . "\e$,43D\e(B")
187 ("\e$,1?A\e(B" . "\\e$,44\7f\e(B")
188 ("\e$,1>j\e(B" . "\e$,43E\e(B")
189 ("\e$,1?B\e(B" . "\\e$,45 \e(B")
190 ("\e$,1>k\e(B" . "\e$,43F4\7f\e(B")
191 ("\e$,1?C\e(B" . "\\e$,45$\e(B")
192 ("\e$,1?`\e(B" . "\e$,43F5 \e(B")
193 ("\e$,1?D\e(B" . "\\e$,45%\e(B")
194 ;;("\e$,1>l\e(B" . nil) ; not implemented.
195 ;;("\e$,1?a\e(B" . nil)
196 ("\e$,1>n\e(B" . "\e$,43G\e(B")
197 ("\e$,1>o\e(B" . "\e$,43H\e(B")
198 ("\e$,1>p\e(B" . "\e$,43I\e(B")
199 ("\e$,1?F\e(B" . "\\e$,45&\e(B")
200 ("\e$,1?G\e(B" . "\\e$,45&4~\e(B")
201 ("\e$,1?H\e(B" . "\\e$,45&5'\e(B")
202 ("\e$,1>r\e(B" . "\e$,43J\e(B")
203 ("\e$,1?J\e(B" . "\e$,45&5 \e(B")
204 ("\e$,1>s\e(B" . "\e$,43K\e(B")
205 ("\e$,1?K\e(B" . "\\e$,45&5 4~\e(B")
206 ("\e$,1>t\e(B" . "\e$,43L\e(B")
207 ("\e$,1?L\e(B" . "\\e$,45(\e(B")
208 ("\e$,1>b\e(B" . "\e$,43M\e(B")
209 ("\e$,1>c\e(B" . "\e$,43N\e(B")
210 ("\e$,1>u?M\e(B" . "\e$,43O5)\e(B") ("\e$,1>u\e(B" . "\e$,43O\e(B") ("\e$,1>u??\e(B" . "\e$,43P\e(B") ("\e$,1>u?@\e(B" . "\e$,43P4~\e(B")
211 ("\e$,1>v?M\e(B" . "\e$,43S5)\e(B") ("\e$,1>v\e(B" . "\e$,43S\e(B") ("\e$,1>v??\e(B" . "\e$,43T\e(B") ("\e$,1>v?@\e(B" . "\e$,43T4~\e(B") ("\e$,1>v?F\e(B" . "\e$,43S5&\e(B") ("\e$,1>v?G\e(B" . "\e$,43S5&4~\e(B") ("\e$,1>v?H\e(B" . "\e$,43S5&5'\e(B") ("\e$,1>v?J\e(B" . "\e$,43S5&5&5 \e(B") ("\e$,1>v?K\e(B" . "\e$,43S5&5&5 4~\e(B") ("\e$,1>v?L\e(B" . "\e$,43S5(\e(B")
212 ("\e$,1>w?M\e(B" . "\e$,43V5)\e(B") ("\e$,1>w\e(B" . "\e$,43V\e(B") ("\e$,1>w??\e(B" . "\e$,43W\e(B") ("\e$,1>w?@\e(B" . "\e$,43W4~\e(B")
213 ("\e$,1>x?M\e(B" . "\e$,43Y5)\e(B") ("\e$,1>x\e(B" . "\e$,43Y\e(B") ("\e$,1>x??\e(B" . "\e$,43Z\e(B") ("\e$,1>x?@\e(B" . "\e$,43Z4~\e(B")
214 ("\e$,1>y?M\e(B" . "\e$,43\5)\e(B") ("\e$,1>y\e(B" . "\e$,43\\e(B")
215 ("\e$,1>z?M\e(B" . "\e$,43^5)\e(B") ("\e$,1>z\e(B" . "\e$,43^\e(B") ("\e$,1>z??\e(B" . "\e$,43_\e(B") ("\e$,1>z?@\e(B" . "\e$,43_4~\e(B")
216 ("\e$,1>{?M\e(B" . "\e$,43a5)\e(B") ("\e$,1>{\e(B" . "\e$,43a\e(B") ("\e$,1>{??\e(B" . "\e$,43b\e(B") ("\e$,1>{?@\e(B" . "\e$,43b4~\e(B")
217 ("\e$,1>|?M\e(B" . "\e$,43d5)\e(B") ("\e$,1>|\e(B" . "\e$,43d\e(B") ("\e$,1>|??\e(B" . "\e$,43f\e(B") ("\e$,1>|?@\e(B" . "\e$,43f4~\e(B") ("\e$,1>|?F\e(B" . "\e$,43e5&\e(B") ("\e$,1>|?G\e(B" . "\e$,43e5&4~\e(B") ("\e$,1>|?H\e(B" . "\e$,43e5&5'\e(B") ("\e$,1>|?J\e(B" . "\e$,43e5&5&5 \e(B") ("\e$,1>|?K\e(B" . "\e$,43e5&5&5 4~\e(B") ("\e$,1>|?L\e(B" . "\e$,43e5(\e(B")
218 ("\e$,1>}?M\e(B" . "\e$,44a4z3h4\7f5)\e(B") ("\e$,1>}\e(B" . "\e$,44a4z3h4\7f\e(B") ("\e$,1>}??\e(B" . "\e$,44b3h4\7f\e(B") ("\e$,1>}?@\e(B" . "\e$,44b3h4\7f4~\e(B") ("\e$,1>}?B\e(B". "\e$,44a4z3h5 \e(B") ("\e$,1>}?J\e(B". "\e$,44a5&3h5 \e(B") ("\e$,1>}?K\e(B". "\e$,44a5&3h5 4~\e(B")
219 ("\e$,1>~?M\e(B" . "\e$,43j5)\e(B") ("\e$,1>~\e(B" . "\e$,43j\e(B")
220 ("\e$,1>\7f?M\e(B" . "\e$,43m5)\e(B") ("\e$,1>\7f\e(B" . "\e$,43l\e(B") ("\e$,1?#?>\e(B" . "\e$,43m4{\e(B") ("\e$,1>\7f??\e(B" . "\e$,43n\e(B") ("\e$,1>\7f?@\e(B" . "\e$,43n4~\e(B") ("\e$,1>\7f?F\e(B" . "\e$,43m5&\e(B") ("\e$,1>\7f?G\e(B" . "\e$,43m5&4~\e(B") ("\e$,1>\7f?H\e(B" . "\e$,43m5&5'\e(B") ("\e$,1>\7f?J\e(B" . "\e$,43m5&5&5 \e(B") ("\e$,1>\7f?K\e(B" . "\e$,43m5&5&5 4~\e(B") ("\e$,1>\7f?L\e(B" . "\e$,43m5(\e(B")
221 ("\e$,1? ?M\e(B" . "\e$,43p5)\e(B") ("\e$,1? \e(B" . "\e$,43p\e(B") ("\e$,1? ??\e(B" . "\e$,43q\e(B") ("\e$,1? ?@\e(B" . "\e$,43q4~\e(B")
222 ("\e$,1?!?M\e(B" . "\e$,43s5)\e(B") ("\e$,1?!\e(B" . "\e$,43s\e(B") ("\e$,1?!??\e(B" . "\e$,43t\e(B") ("\e$,1?!?@\e(B" . "\e$,43t4~\e(B")
223 ("\e$,1?"?M\e(B" . "\e$,43v5)\e(B") ("\e$,1?"\e(B" . "\e$,43v\e(B") ("\e$,1?"??\e(B" . "\e$,43w\e(B") ("\e$,1?"?@\e(B" . "\e$,43w4~\e(B")
224 ("\e$,1?#?M\e(B" . "\e$,43z5)\e(B") ("\e$,1?#\e(B" . "\e$,43y\e(B") ("\e$,1?#?>\e(B" . "\e$,43z4{\e(B") ("\e$,1?#??\e(B" . "\e$,43{\e(B") ("\e$,1?#?@\e(B" . "\e$,43{4~\e(B") ("\e$,1?#?F\e(B" . "\e$,43z5&\e(B") ("\e$,1?#?G\e(B" . "\e$,43z5&4~\e(B") ("\e$,1?#?H\e(B" . "\e$,43z5&5'\e(B") ("\e$,1?#?J\e(B" . "\e$,43z5&5&5 \e(B") ("\e$,1?#?K\e(B" . "\e$,43z5&5&5 4~\e(B") ("\e$,1?#?L\e(B" . "\e$,43z5(\e(B")
225 ("\e$,1?$?M\e(B" . "\e$,43}5)\e(B") ("\e$,1?$\e(B" . "\e$,43}\e(B") ("\e$,1?$??\e(B" . "\e$,43~\e(B") ("\e$,1?$?@\e(B" . "\e$,43~4~\e(B")
226 ("\e$,1?%?M\e(B" . "\e$,44B5)\e(B") ("\e$,1?%\e(B" . "\e$,44B\e(B") ("\e$,1?%??\e(B" . "\e$,44C\e(B") ("\e$,1?%?@\e(B" . "\e$,44C4~\e(B")
227 ("\e$,1?&?M\e(B" . "\e$,44E5)\e(B") ("\e$,1?&\e(B" . "\e$,44E\e(B") ("\e$,1?&??\e(B" . "\e$,44F\e(B") ("\e$,1?&?@\e(B" . "\e$,44F4~\e(B")
228 ("\e$,1?'?M\e(B" . "\e$,44H5)\e(B") ("\e$,1?'\e(B" . "\e$,44H\e(B") ("\e$,1?'??\e(B" . "\e$,44I\e(B") ("\e$,1?'?@\e(B" . "\e$,44I4~\e(B")
229 ("\e$,1?(?M\e(B" . "\e$,44K5)\e(B") ("\e$,1?(\e(B" . "\e$,44K\e(B") ("\e$,1?(??\e(B" . "\e$,44L\e(B") ("\e$,1?(?@\e(B" . "\e$,44L4~\e(B")
230 ("\e$,1?*?M\e(B" . "\e$,44N5)\e(B") ("\e$,1?*\e(B" . "\e$,44N\e(B") ("\e$,1?*??\e(B" . "\e$,44O\e(B") ("\e$,1?*?@\e(B" . "\e$,44O4~\e(B") ("\e$,1?*?A\e(B" . "\e$,44N5"\e(B") ("\e$,1?*?B\e(B" . "\e$,44N5#\e(B") ("\e$,1?*?J\e(B" . "\e$,44N5&5#\e(B") ("\e$,1?*?K\e(B" . "\e$,44N5&5#4~\e(B")
231 ("\e$,1?+?M\e(B" . "\e$,44Q5)\e(B") ("\e$,1?+\e(B" . "\e$,44Q\e(B") ("\e$,1?+??\e(B" . "\e$,44R\e(B") ("\e$,1?+?@\e(B" . "\e$,44R4~\e(B") ("\e$,1?+?A\e(B" . "\e$,44Q5"\e(B") ("\e$,1?+?B\e(B" . "\e$,44Q5#\e(B") ("\e$,1?+?J\e(B" . "\e$,44Q5&5#\e(B") ("\e$,1?+?K\e(B" . "\e$,44Q5&5#4~\e(B")
232 ("\e$,1?,?M\e(B" . "\e$,44W5)\e(B") ("\e$,1?,\e(B" . "\e$,44V\e(B") ("\e$,1?,?>\e(B". "\e$,44W4{\e(B") ("\e$,1?,??\e(B" . "\e$,44X\e(B") ("\e$,1?,?@\e(B" . "\e$,44X4~\e(B") ("\e$,1?,?F\e(B" . "\e$,44W5&\e(B") ("\e$,1?,?G\e(B" . "\e$,44W5&4~\e(B") ("\e$,1?,?H\e(B" . "\e$,44W5&5'\e(B") ("\e$,1?,?J\e(B" . "\e$,44W5&5&5 \e(B") ("\e$,1?,?K\e(B" . "\e$,44W5&5&5 4~\e(B") ("\e$,1?,?L\e(B" . "\e$,44W5(\e(B")
233 ("\e$,1?-?M\e(B" . "\e$,44Z5)\e(B") ("\e$,1?-\e(B" . "\e$,44Z\e(B") ("\e$,1?-??\e(B" . "\e$,44[\e(B") ("\e$,1?-?@\e(B" . "\e$,44[4~\e(B")
234 ("\e$,1?.?M\e(B" . "\e$,44h5!5)\e(B") ("\e$,1?.\e(B" . "\e$,44h4z4\7f\e(B") ("\e$,1?.?>\e(B" . "\e$,44h4z5!4{\e(B") ("\e$,1?.??\e(B" . "\e$,44i4\7f\e(B") ("\e$,1?.?@\e(B" . "\e$,44i4\7f4~\e(B") ("\e$,1?.?J\e(B". "\e$,44h5&5 \e(B") ("\e$,1?.?K\e(B". "\e$,44h5&5 4~\e(B")
235 ("\e$,1?/?M\e(B" . "\e$,44^4z5!5)\e(B") ("\e$,1?/\e(B" . "\e$,44^4z4\7f\e(B") ("\e$,1?/?>\e(B" . "\e$,44^4z5!4{\e(B")("\e$,1?/??\e(B" . "\e$,44_4\7f\e(B") ("\e$,1?/?@\e(B" . "\e$,44_4\7f4~\e(B") ("\e$,1?/?J\e(B" . "\e$,44^5&5 \e(B") ("\e$,1?/?K\e(B" . "\e$,44^5&5 4~\e(B")
236 ("\e$,1?0?M\e(B" . "\e$,44a5)\e(B") ("\e$,1?0\e(B" . "\e$,44a\e(B") ("\e$,1?0??\e(B" . "\e$,44b\e(B") ("\e$,1?0?@\e(B" . "\e$,44b4~\e(B")
237 ("\e$,1?0?M\e(B" . "\e$,44a5)\e(B") ("\e$,1?0\e(B" . "\e$,44a\e(B") ("\e$,1?0??\e(B" . "\e$,44b\e(B") ("\e$,1?0?@\e(B" . "\e$,44b4~\e(B")
238 ("\e$,1?2?M\e(B" . "\e$,44e5)\e(B") ("\e$,1?2\e(B" . "\e$,44d\e(B") ("\e$,1?2?>\e(B" . "\e$,44e4{\e(B") ("\e$,1?2??\e(B" . "\e$,44f\e(B") ("\e$,1?2?@\e(B" . "\e$,44f4~\e(B") ("\e$,1?2?F\e(B" . "\e$,44e5&\e(B") ("\e$,1?2?G\e(B" . "\e$,44e5&4~\e(B") ("\e$,1?2?H\e(B" . "\e$,44e5&5'\e(B") ("\e$,1?2?J\e(B" . "\e$,44e5&5&5 \e(B") ("\e$,1?2?K\e(B" . "\e$,44e5&5&5 4~\e(B") ("\e$,1?2?L\e(B" . "\e$,44e5(\e(B")
239 ("\e$,1?5?M\e(B" . "\e$,44h5)\e(B") ("\e$,1?5\e(B" . "\e$,44h\e(B") ("\e$,1?5??\e(B" . "\e$,44i\e(B") ("\e$,1?5?@\e(B" . "\e$,44i4~\e(B") ("\e$,1?5?A\e(B" . "\e$,44h5"\e(B") ("\e$,1?5?B\e(B" . "\e$,44h5#\e(B") ("\e$,1?5?J\e(B" . "\e$,44h5&5#\e(B") ("\e$,1?5?K\e(B" . "\e$,44h5&5#4~\e(B")
240 ("\e$,1?6?M\e(B" . "\e$,44k5)\e(B") ("\e$,1?6\e(B" . "\e$,44k\e(B") ("\e$,1?6??\e(B" . "\e$,44l\e(B") ("\e$,1?6?@\e(B" . "\e$,44l4~\e(B")
241 ("\e$,1?7?M\e(B" . "\e$,44n5)\e(B") ("\e$,1?7\e(B" . "\e$,44n\e(B") ("\e$,1?7??\e(B" . "\e$,44o\e(B") ("\e$,1?7?@\e(B" . "\e$,44o4~\e(B")
242 ("\e$,1?8?M\e(B" . "\e$,44q5)\e(B") ("\e$,1?8\e(B" . "\e$,44q\e(B") ("\e$,1?8??\e(B" . "\e$,44r\e(B") ("\e$,1?8?@\e(B" . "\e$,44r4~\e(B")
243 ("\e$,1?9?M\e(B" . "\e$,44t5)\e(B") ("\e$,1?9\e(B" . "\e$,44t\e(B") ("\e$,1?9??\e(B" . "\e$,44u\e(B") ("\e$,1?9?@\e(B" . "\e$,44u4~\e(B")
244 ("\e$,1?3?M\e(B" . "\e$,44w5)\e(B") ("\e$,1?3\e(B" . "\e$,44w\e(B") ("\e$,1?3??\e(B" . "\e$,44x\e(B") ("\e$,1?3?@\e(B" . "\e$,44x4~\e(B"))
245 "Kannada characters to glyphs conversion table.
246 Default value contains only the basic rules.")
247
248 (defvar knd-char-glyph-hash
249 (let* ((hash (make-hash-table :test 'equal)))
250 (mapc (function (lambda (x) (puthash (car x) (cdr x) hash)))
251 knd-char-glyph)
252 hash))
253
254 (defvar knd-char-glyph-regexp
255 (kannada-regexp-of-hashtbl-keys knd-char-glyph-hash))
256
257 (defvar knd-conjunct-glyph
258 '(("\e$,1>u\e(B" . "\e$,43Q\e(B") ("\e$,1>v\e(B" . "\e$,43U\e(B") ("\e$,1>w\e(B" . "\e$,43X\e(B") ("\e$,1>x\e(B" . "\e$,43[\e(B") ("\e$,1>y\e(B" . "\e$,43]\e(B")
259 ("\e$,1>z\e(B" . "\e$,43`\e(B") ("\e$,1>{\e(B" . "\e$,43c\e(B") ("\e$,1>|\e(B" . "\e$,43g\e(B") ("\e$,1>}\e(B" . "\e$,43i\e(B") ("\e$,1>~\e(B" . "\e$,43k\e(B")
260 ("\e$,1>\7f\e(B" . "\e$,43o\e(B") ("\e$,1? \e(B" . "\e$,43r\e(B") ("\e$,1?!\e(B" . "\e$,43u\e(B") ("\e$,1?"\e(B" . "\e$,43x\e(B") ("\e$,1?#\e(B" . "\e$,43|\e(B")
261 ("\e$,1?$\e(B" . "\e$,44A\e(B") ("\e$,1?%\e(B" . "\e$,44D\e(B") ("\e$,1?&\e(B" . "\e$,44G\e(B") ("\e$,1?'\e(B" . "\e$,44J\e(B") ("\e$,1?(\e(B" . "\e$,44M\e(B")
262 ("\e$,1?*\e(B" . "\e$,44P\e(B") ("\e$,1?+\e(B" . "\e$,44U\e(B") ("\e$,1?,\e(B" . "\e$,44Y\e(B") ("\e$,1?-\e(B" . "\e$,44\\e(B") ("\e$,1?.\e(B" . "\e$,44]\e(B")
263 ("\e$,1?/\e(B" . "\e$,44`\e(B") ("\e$,1?0\e(B" . "\e$,44c\e(B") ("\e$,1?2\e(B" . "\e$,44g\e(B") ("\e$,1?3\e(B" . "\e$,44y\e(B") ("\e$,1?5\e(B" . "\e$,44j\e(B")
264 ("\e$,1?6\e(B" . "\e$,44m\e(B") ("\e$,1?7\e(B" . "\e$,44p\e(B") ("\e$,1?8\e(B" . "\e$,44s\e(B") ("\e$,1?9\e(B" . "\e$,44v\e(B"))
265 "Kannada characters to conjunct glyphs conversion table.")
266
267 (defvar knd-conjunct-glyph-hash
268 (let* ((hash (make-hash-table :test 'equal)))
269 (mapc (function (lambda (x) (puthash (car x) (cdr x) hash)))
270 knd-conjunct-glyph)
271 hash))
272
273 (defvar knd-conjunct-glyph-regexp
274 (kannada-regexp-of-hashtbl-vals knd-conjunct-glyph-hash))
275
276 (mapc
277 (function (lambda (x)
278 (put-char-code-property (aref (cdr x) 0) 'reference-point '(5 . 3))))
279 knd-conjunct-glyph)
280
281 ;; glyph-to-glyph conversion table.
282 ;; it is supposed that glyphs are ordered in
283 ;; [consonant/nukta] - [matra/virama] - [preceding-r] - [anuswar].
284
285 (defvar knd-glyph-glyph
286 '(("\e$,45$4A\e(B" . "\e$,45*\e(B")
287 ("\e$,45'4A\e(B" . "\e$,45+\e(B")
288 ("\e$,44A3g\e(B" . "\e$,45,\e(B")
289 ("\e$,45$3Q\e(B" . "\e$,45-\e(B")))
290
291 (defvar knd-glyph-glyph-hash
292 (let* ((hash (make-hash-table :test 'equal)))
293 (mapc (function (lambda (x) (puthash (car x) (cdr x) hash)))
294 knd-glyph-glyph)
295 hash))
296 (defvar knd-glyph-glyph-regexp
297 (kannada-regexp-of-hashtbl-keys knd-glyph-glyph-hash))
298
299 (defun knd-charseq (from &optional to)
300 (if (null to) (setq to from))
301 (mapcar (function (lambda (x) (indian-glyph-char x 'kannada)))
302 (kannada-range from to)))
303
304 (defvar knd-glyph-cv
305 (append
306 (knd-charseq #x40 #x50)
307 (knd-charseq #x52 #x54)
308 (knd-charseq #x56 #x57)
309 (knd-charseq #x59 #x5a)
310 (knd-charseq #x5c)
311 (knd-charseq #x5e #x5f)
312 (knd-charseq #x61 #x62)
313 (knd-charseq #x64 #x66)
314 (knd-charseq #x6a)
315 (knd-charseq #x6c #x6e)
316 (knd-charseq #x70 #x71)
317 (knd-charseq #x73 #x74)
318 (knd-charseq #x76 #x77)
319 (knd-charseq #x79 #x7b)
320 (knd-charseq #x7d #x7e)
321 (knd-charseq #xa2 #xa3)
322 (knd-charseq #xa5 #xa6)
323 (knd-charseq #xa8 #xa9)
324 (knd-charseq #xab #xac)
325 (knd-charseq #xae #xaf)
326 (knd-charseq #xb1 #xb2)
327 (knd-charseq #xb6 #xb8)
328 (knd-charseq #xb6 #xb8)
329 (knd-charseq #xba #xbb)
330 (knd-charseq #xbe #xbf)
331 (knd-charseq #xc1 #xc2)
332 (knd-charseq #xc4 #xc6)
333 (knd-charseq #xc8 #xc9)
334 (knd-charseq #xcb #xcc)
335 (knd-charseq #xce #xcf)
336 (knd-charseq #xd1 #xd2)
337 (knd-charseq #xd4 #xd5)
338 (knd-charseq #xd7 #xd8)
339 (knd-charseq #xc3))
340 "Kannada Consonants/Vowels/Nukta Glyphs")
341
342 (defvar knd-glyph-space
343 (knd-charseq #xb3 #xb4)
344 "Kannada Spacing Glyphs")
345
346 (defvar knd-glyph-right-modifier
347 (append
348 (knd-charseq #xdb #xdd)
349 (knd-charseq #xdf)
350 (knd-charseq #xe0 #xe3)
351 (knd-charseq #xe9))
352 "Kannada Modifiers attached at the right side.")
353
354 (defvar knd-glyph-right-modifier-regexp
355 (concat "[" knd-glyph-right-modifier "]"))
356
357 (defvar knd-glyph-jha-tail
358 (knd-charseq #x68)
359 "Kannada tail for jha.")
360
361 (defvar knd-glyph-top-matra
362 (append
363 (knd-charseq #xda)
364 (knd-charseq #xdd)
365 (knd-charseq #xe6)
366 (knd-charseq #xe8))
367 "Kannada Matras attached at the top side.")
368
369 (defvar knd-glyph-bottom-matra
370 (append
371 (knd-charseq #xe4 #xe5)
372 (knd-charseq #xe7))
373 "Kannada Matras attached at the bottom.")
374
375 (defvar knd-glyph-end-marks
376 (append
377 (knd-charseq #x25)
378 (knd-charseq #x4d #x4e)
379 (knd-charseq #xde))
380 "Kannada end marks: arkavattu, virama, au and diirghaa.")
381
382 (defvar knd-glyph-bottom-modifier
383 (append
384 (knd-charseq #x51)
385 (knd-charseq #x55)
386 (knd-charseq #x58)
387 (knd-charseq #x5b)
388 (knd-charseq #x5d)
389 (knd-charseq #x60)
390 (knd-charseq #x63)
391 (knd-charseq #x67)
392 (knd-charseq #x69)
393 (knd-charseq #x6b)
394 (knd-charseq #x6f)
395 (knd-charseq #x72)
396 (knd-charseq #x75)
397 (knd-charseq #x78)
398 (knd-charseq #x7c)
399 (knd-charseq #xa1)
400 (knd-charseq #xa4)
401 (knd-charseq #xa7)
402 (knd-charseq #xaa)
403 (knd-charseq #xad)
404 (knd-charseq #xb0)
405 (knd-charseq #xb5)
406 (knd-charseq #xb9)
407 (knd-charseq #xbc #xbd)
408 (knd-charseq #xc0)
409 (knd-charseq #xc3)
410 (knd-charseq #xc7)
411 (knd-charseq #xca)
412 (knd-charseq #xcd)
413 (knd-charseq #xd0)
414 (knd-charseq #xd3)
415 (knd-charseq #xd6)
416 (knd-charseq #xd9)
417 (knd-charseq #xea #xef))
418 "Kannada Modifiers attached at the bottom.")
419
420 (defvar knd-glyph-order
421 `((,knd-glyph-cv . 1)
422 (,knd-glyph-top-matra . 2)
423 (,knd-glyph-jha-tail . 3)
424 (,knd-glyph-right-modifier . 4)
425 (,knd-glyph-space . 5)
426 (,knd-glyph-bottom-modifier . 5)
427 (,knd-glyph-bottom-matra . 6)
428 (,knd-glyph-end-marks . 7)
429 ))
430
431 (mapc
432 (function (lambda (x)
433 (mapc
434 (function (lambda (y)
435 (put-char-code-property y 'composition-order (cdr x))))
436 (car x))))
437 knd-glyph-order)
438
439 (defun kannada-compose-syllable-string (string)
440 (with-temp-buffer
441 (insert (decompose-string string))
442 (kannada-compose-syllable-region (point-min) (point-max))
443 (buffer-string)))
444
445 ;; kch
446 (defun kannada-compose-syllable-region (from to)
447 "Compose kannada syllable in region FROM to TO."
448 (let ((glyph-str nil) (cons-num 0) (glyph-str-list nil)
449 (last-virama nil) (preceding-r nil) (last-modifier nil)
450 (last-char (char-before to)) match-str pos
451 glyph-block split-pos (conj nil) (rest nil))
452 (save-excursion
453 (save-restriction
454 ;;; *** char-to-glyph conversion ***
455 ;; Special rule 1. -- Last virama must be preserved.
456 (if (eq last-char ?\e$,1?M\e(B)
457 (progn
458 (setq last-virama t)
459 (narrow-to-region from (1- to)))
460 (narrow-to-region from to))
461 (goto-char (point-min))
462 ;; Special rule 2. -- preceding "r virama" must be modifier.
463 (when (looking-at "\e$,1?0?M\e(B.")
464 (setq preceding-r t)
465 (goto-char (+ 2 (point))))
466 ;; remove conjunct consonants
467 (while (re-search-forward knd-char-glyph-regexp nil t)
468 (setq match-str (match-string 0))
469 (if (and (string-match kannada-consonant match-str)
470 (> cons-num 0))
471 (progn
472 (setq conj (concat conj (gethash (match-string 0 match-str)
473 knd-conjunct-glyph-hash)))
474 (setq match-str (replace-match "" t nil match-str))
475 (if (string-match "\e$,1?M\e(B" rest)
476 (setq rest (replace-match "" t nil rest)))))
477 (setq rest (concat rest match-str))
478 ;; count the number of consonant-glyhs.
479 (if (string-match kannada-consonant match-str)
480 (setq cons-num (1+ cons-num))))
481 ;; translate the rest characters into glyphs
482 (setq pos 0)
483 (while (string-match knd-char-glyph-regexp rest pos)
484 (setq match-str (match-string 0 rest))
485 (setq pos (match-end 0))
486 (setq glyph-str
487 (concat glyph-str (gethash match-str knd-char-glyph-hash))))
488
489 (if conj (setq glyph-str (concat glyph-str conj)))
490 (if last-virama (setq glyph-str (concat glyph-str "\e$,45)\e(B"))
491 (goto-char (point-min))
492 (if (re-search-forward kannada-consonant-needs-twirl nil t)
493 (progn
494 (setq match-str (match-string 0))
495 (setq glyph-str (concat glyph-str "\e$,44z\e(B")))))
496 ;; preceding-r must be attached
497 (if preceding-r
498 (setq glyph-str (concat glyph-str "\e$,43%\e(B")))
499 ;;; *** glyph-to-glyph conversion ***
500 (when (string-match knd-glyph-glyph-regexp glyph-str)
501 (setq glyph-str
502 (replace-match (gethash (match-string 0 glyph-str)
503 knd-glyph-glyph-hash)
504 nil t glyph-str)))
505 ;;; *** glyph reordering ***
506 (while (setq split-pos (string-match "\e$,45)\e(B\\|.$" glyph-str))
507 (setq glyph-block (substring glyph-str 0 (1+ split-pos)))
508 (setq glyph-str (substring glyph-str (1+ split-pos)))
509 (setq
510 glyph-block
511 (sort (string-to-list glyph-block)
512 (function (lambda (x y)
513 (< (get-char-code-property x 'composition-order)
514 (get-char-code-property y 'composition-order))))))
515 (setq glyph-str-list (nconc glyph-str-list glyph-block)))
516 ;;; *** insert space glyphs for kerning ***
517 (if (> cons-num 0)
518 (let ((curr glyph-str-list) (prev nil) (last-bott nil) bott co)
519 (while curr
520 (setq co (get-char-code-property
521 (car curr) 'composition-order)
522 bott (or (eq co 5) (eq co 6)))
523 (if (and bott last-bott)
524 (setcdr prev (cons ?\e$,44T\e(B curr)))
525 (setq last-bott bott prev curr curr (cdr curr)))))
526 ;; concatenate and attach reference-points.
527 (setq glyph-str
528 (cdr
529 (apply
530 'nconc
531 (mapcar
532 (function (lambda (x)
533 (list
534 (or (get-char-code-property x 'reference-point)
535 '(5 . 3) ;; default reference point.
536 )
537 x)))
538 glyph-str-list))))))
539 (compose-region from to glyph-str)))
540
541 (provide 'knd-util)
542
543 ;;; arch-tag: 78d32230-a960-46a5-b622-61ed6ffcf8fc
544 ;;; knd-util.el ends here