*** empty log message ***
[emacs.git] / lisp / language / ethio-util.el
blob5dde78ec832abfe437fd12fe415a0d2b7e658934
1 ;;; ethio-util.el --- utilities for Ethiopic -*- coding: iso-2022-7bit; -*-
3 ;; Copyright (C) 1997, 2001 Electrotechnical Laboratory, JAPAN.
4 ;; Licensed to the Free Software Foundation.
6 ;; Keywords: mule, multilingual, Ethiopic
8 ;; This file is part of GNU Emacs.
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.
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.
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.
25 ;; Author: TAKAHASHI Naoto <ntakahas@m17n.org>
27 ;;; Code:
29 ;; Information for exiting Ethiopic environment.
30 (defvar exit-ethiopic-environment-data nil)
32 ;;;###autoload
33 (defun setup-ethiopic-environment-internal ()
34 (let ((key-bindings '((" " . ethio-insert-space)
35 ([?\S- ] . ethio-insert-ethio-space)
36 ([?\C-'] . ethio-gemination)
38 ;; these old bindings conflict
39 ;; with Emacs' binding policy
41 ;; ([f2] . ethio-toggle-space)
42 ;; ([S-f2] . ethio-replace-space) ; as requested
43 ;; ([f3] . ethio-toggle-punctuation)
44 ;; ([f4] . ethio-sera-to-fidel-buffer)
45 ;; ([S-f4] . ethio-sera-to-fidel-region)
46 ;; ([C-f4] . ethio-sera-to-fidel-mail-or-marker)
47 ;; ([f5] . ethio-fidel-to-sera-buffer)
48 ;; ([S-f5] . ethio-fidel-to-sera-region)
49 ;; ([C-f5] . ethio-fidel-to-sera-mail-or-marker)
50 ;; ([f6] . ethio-modify-vowel)
51 ;; ([f7] . ethio-replace-space)
52 ;; ([f8] . ethio-input-special-character)
54 ;; this is the rewritten bindings
56 ([f3] . ethio-fidel-to-sera-buffer)
57 ([S-f3] . ethio-fidel-to-sera-region)
58 ([C-f3] . ethio-fidel-to-sera-mail-or-marker)
59 ([f4] . ethio-sera-to-fidel-buffer)
60 ([S-f4] . ethio-sera-to-fidel-region)
61 ([C-f4] . ethio-sera-to-fidel-mail-or-marker)
62 ([S-f5] . ethio-toggle-punctuation)
63 ([S-f6] . ethio-modify-vowel)
64 ([S-f7] . ethio-replace-space)
65 ([S-f8] . ethio-input-special-character)
66 ([C-f9] . ethio-toggle-space)
67 ([S-f9] . ethio-replace-space) ; as requested
69 kb)
70 (while key-bindings
71 (setq kb (car (car key-bindings)))
72 (setq exit-ethiopic-environment-data
73 (cons (cons kb (global-key-binding kb))
74 exit-ethiopic-environment-data))
75 (global-set-key kb (cdr (car key-bindings)))
76 (setq key-bindings (cdr key-bindings))))
78 (add-hook 'quail-activate-hook 'ethio-select-a-translation)
79 (add-hook 'find-file-hooks 'ethio-find-file)
80 (add-hook 'write-file-hooks 'ethio-write-file)
81 (add-hook 'after-save-hook 'ethio-find-file))
83 (defun exit-ethiopic-environment ()
84 "Exit Ethiopic language environment"
85 (while exit-ethiopic-environment-data
86 (global-set-key (car (car exit-ethiopic-environment-data))
87 (cdr (car exit-ethiopic-environment-data)))
88 (setq exit-ethiopic-environment-data
89 (cdr exit-ethiopic-environment-data)))
91 (remove-hook 'quail-activate-hook 'ethio-select-a-translation)
92 (remove-hook 'find-file-hooks 'ethio-find-file)
93 (remove-hook 'write-file-hooks 'ethio-write-file)
94 (remove-hook 'after-save-hook 'ethio-find-file))
97 ;; ETHIOPIC UTILITY FUNCTIONS
100 ;; If the filename ends in ".sera", editing is done in fidel
101 ;; but file I/O is done in SERA.
103 ;; If the filename ends in ".java", editing is done in fidel
104 ;; but file I/O is done in the \uXXXX style, where XXXX is
105 ;; the Unicode codepoint for the Ethiopic character.
107 ;; If the filename ends in ".tex", editing is done in fidel
108 ;; but file I/O is done in EthioTeX format.
110 ;; To automatically convert Ethiopic text to SERA format when sending mail,
111 ;; (add-hook 'mail-send-hook 'ethio-fidel-to-sera-mail)
113 ;; To automatically convert SERA format to Ethiopic when receiving mail,
114 ;; (add-hook 'rmail-show-message-hook 'ethio-sera-to-fidel-mail)
116 ;; To automatically convert Ethiopic text to SERA format when posting news,
117 ;; (add-hook 'news-inews-hook 'ethio-fidel-to-sera-mail)
120 ;; users' preference
123 (defvar ethio-primary-language 'tigrigna
124 "*Symbol that defines the primary language in SERA --> FIDEL conversion.
125 The value should be one of: `tigrigna', `amharic' or `english'.")
127 (defvar ethio-secondary-language 'english
128 "*Symbol that defines the secondary language in SERA --> FIDEL conversion.
129 The value should be one of: `tigrigna', `amharic' or `english'.")
131 (defvar ethio-use-colon-for-colon nil
132 "*Non-nil means associate ASCII colon with Ethiopic colon.
133 If nil, associate ASCII colon with Ethiopic word separator, i.e., two
134 vertically stacked dots. All SERA <--> FIDEL converters refer this
135 variable.")
137 (defvar ethio-use-three-dot-question nil
138 "*Non-nil means associate ASCII question mark with Ethiopic old style question mark (three vertically stacked dots).
139 If nil, associate ASCII question mark with Ethiopic stylised question
140 mark. All SERA <--> FIDEL converters refer this variable.")
142 (defvar ethio-quote-vowel-always nil
143 "*Non-nil means always put an apostrophe before an isolated vowel (except at word initial) in FIDEL --> SERA conversion.
144 If nil, put an apostrophe only between a sixth-form consonant and an
145 isolated vowel.")
147 (defvar ethio-W-sixth-always nil
148 "*Non-nil means convert the Wu-form of a 12-form consonant to \"W'\" instead of \"Wu\" in FIDEL --> SERA conversion.")
150 (defvar ethio-numeric-reduction 0
151 "*Degree of reduction in converting Ethiopic digits into Arabic digits.
152 Should be 0, 1 or 2.
153 For example, ({10}{9}{100}{80}{7}) is converted into:
154 `10`9`100`80`7 if `ethio-numeric-reduction' is 0,
155 `109100807 if `ethio-numeric-reduction' is 1,
156 `10900807 if `ethio-numeric-reduction' is 2.")
158 (defvar ethio-implicit-period-conversion t
159 "*Non-nil means replacing the Ethiopic dot at the end of an Ethiopic sentence
160 with an Ethiopic full stop.")
162 (defvar ethio-java-save-lowercase nil
163 "*Non-nil means save Ethiopic characters in lowercase hex numbers to Java files.
164 If nil, use uppercases.")
167 ;; SERA to FIDEL
170 (defconst ethio-sera-to-fidel-table
172 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil
173 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil
174 ;;; SP
175 (" "
176 (?: (if ethio-use-colon-for-colon " \e$(3$l\e(B" "\e$(3$h\e(B")
177 (32 (if ethio-use-colon-for-colon " \e$(3$l\e(B " "\e$(3$h\e(B"))
178 (?- " \e$(3$m\e(B")
179 (?: " \e$(3$i\e(B")
180 (?| (if ethio-use-colon-for-colon " \e$(3$l\e(B|" " \e$(3$h\e(B|")
181 (?: " \e$(3$o\e(B"))))
183 ;;; ! " # $ % & '
184 nil nil nil nil nil nil ("" (?' "\e$(3%s\e(B"))
185 ;;; ( ) * + , - .
186 nil nil nil nil ("\e$(3$j\e(B") ("-" (?: "\e$(3$l\e(B")) ("\e$(3%u\e(B")
187 ;;; / 0 1 2 3 4 5 6 7 8 9
188 nil nil nil nil nil nil nil nil nil nil nil
189 ;;; :
190 ((if ethio-use-colon-for-colon "\e$(3$l\e(B" "\e$(3$h\e(B")
191 (32 (if ethio-use-colon-for-colon "\e$(3$l\e(B " "\e$(3$h\e(B"))
192 (?- "\e$(3$m\e(B")
193 (?: "\e$(3$i\e(B")
194 (?| (if ethio-use-colon-for-colon "\e$(3$l\e(B|" "\e$(3$h\e(B|")
195 (?: "\e$(3$o\e(B")))
196 ;;; ; < = >
197 ("\e$(3$k\e(B") ("<" (?< "\e$(3%v\e(B")) nil (">" (?> "\e$(3%w\e(B"))
198 ;;; ?
199 ((if ethio-use-three-dot-question "\e$(3$n\e(B" "\e$(3%x\e(B"))
200 ;;; @
202 ;;; A
203 ("\e$(3"f\e(B" (?2 "\e$(3#8\e(B"))
204 ;;; B
205 ("\e$(3"(\e(B" (?e "\e$(3"#\e(B") (?u "\e$(3"$\e(B") (?i "\e$(3"%\e(B") (?a "\e$(3"&\e(B") (?E "\e$(3"'\e(B") (?o "\e$(3")\e(B")
206 (?W "\e$(3%b\e(B" (?e "\e$(3%2\e(B") (?u "\e$(3%b\e(B") (?i "\e$(3%B\e(B") (?a "\e$(3"*\e(B") (?E "\e$(3%R\e(B")))
207 ;;; C
208 ("\e$(3$4\e(B" (?e "\e$(3$/\e(B") (?u "\e$(3$0\e(B") (?i "\e$(3$1\e(B") (?a "\e$(3$2\e(B") (?E "\e$(3$3\e(B") (?o "\e$(3$5\e(B")
209 (?W "\e$(3$6\e(B" (?a "\e$(3$6\e(B")
210 (?e "\e$(3$4%n\e(B") (?u "\e$(3$4%r\e(B") (?i "\e$(3$4%o\e(B") (?E "\e$(3$4%q\e(B")))
211 ;;; D
212 ("\e$(3#b\e(B" (?e "\e$(3#]\e(B") (?u "\e$(3#^\e(B") (?i "\e$(3#_\e(B") (?a "\e$(3#`\e(B") (?E "\e$(3#a\e(B") (?o "\e$(3#c\e(B")
213 (?W "\e$(3#d\e(B" (?a "\e$(3#d\e(B")
214 (?e "\e$(3#b%n\e(B") (?u "\e$(3#b%r\e(B") (?i "\e$(3#b%o\e(B") (?E "\e$(3#b%q\e(B")))
215 ;;; E
216 ("\e$(3"g\e(B" (?2 "\e$(3#9\e(B"))
217 ;;; F
218 ("\e$(3$T\e(B" (?e "\e$(3$O\e(B") (?u "\e$(3$P\e(B") (?i "\e$(3$Q\e(B") (?a "\e$(3$R\e(B") (?E "\e$(3$S\e(B") (?o "\e$(3$U\e(B")
219 (?W "\e$(3%d\e(B" (?e "\e$(3%4\e(B") (?u "\e$(3%d\e(B") (?i "\e$(3%D\e(B") (?a "\e$(3$V\e(B") (?E "\e$(3%T\e(B"))
220 (?Y "\e$(3$a\e(B" (?a "\e$(3$a\e(B")))
221 ;;; G
222 ("\e$(3$$\e(B" (?e "\e$(3#}\e(B") (?u "\e$(3#~\e(B") (?i "\e$(3$!\e(B") (?a "\e$(3$"\e(B") (?E "\e$(3$#\e(B") (?o "\e$(3$%\e(B")
223 (?W "\e$(3%c\e(B" (?e "\e$(3%3\e(B") (?u "\e$(3%c\e(B") (?i "\e$(3%C\e(B") (?a "\e$(3$&\e(B") (?E "\e$(3%S\e(B")))
224 ;;; H
225 ("\e$(3!6\e(B" (?e "\e$(3!1\e(B") (?u "\e$(3!2\e(B") (?i "\e$(3!3\e(B") (?a "\e$(3!4\e(B") (?E "\e$(3!5\e(B") (?o "\e$(3!7\e(B")
226 (?W "\e$(3!8\e(B" (?a "\e$(3!8\e(B")
227 (?e "\e$(3!6%n\e(B") (?u "\e$(3!6%r\e(B") (?i "\e$(3!6%o\e(B") (?E "\e$(3!6%q\e(B")))
228 ;;; I
229 ("\e$(3"h\e(B" (?2 "\e$(3#:\e(B"))
230 ;;; J
231 ("\e$(3#j\e(B" (?e "\e$(3#e\e(B") (?u "\e$(3#f\e(B") (?i "\e$(3#g\e(B") (?a "\e$(3#h\e(B") (?E "\e$(3#i\e(B") (?o "\e$(3#k\e(B")
232 (?W "\e$(3#l\e(B" (?a "\e$(3#l\e(B")
233 (?e "\e$(3#j%n\e(B") (?u "\e$(3#j%r\e(B") (?i "\e$(3#j%o\e(B") (?E "\e$(3#j%q\e(B")))
234 ;;; K
235 ("\e$(3#"\e(B" (?e "\e$(3"{\e(B") (?u "\e$(3"|\e(B") (?i "\e$(3"}\e(B") (?a "\e$(3"~\e(B") (?E "\e$(3#!\e(B") (?o "\e$(3##\e(B")
236 (?W "\e$(3#*\e(B" (?e "\e$(3#%\e(B") (?u "\e$(3#*\e(B") (?i "\e$(3#'\e(B") (?a "\e$(3#(\e(B") (?E "\e$(3#)\e(B")))
237 ;;; L
238 ("\e$(3!.\e(B" (?e "\e$(3!)\e(B") (?u "\e$(3!*\e(B") (?i "\e$(3!+\e(B") (?a "\e$(3!,\e(B") (?E "\e$(3!-\e(B") (?o "\e$(3!/\e(B")
239 (?W "\e$(3!0\e(B" (?a "\e$(3!0\e(B")
240 (?e "\e$(3!.%n\e(B") (?u "\e$(3!.%r\e(B") (?i "\e$(3!.%o\e(B") (?E "\e$(3!.%q\e(B")))
241 ;;; M
242 ("\e$(3!>\e(B" (?e "\e$(3!9\e(B") (?u "\e$(3!:\e(B") (?i "\e$(3!;\e(B") (?a "\e$(3!<\e(B") (?E "\e$(3!=\e(B") (?o "\e$(3!?\e(B")
243 (?W "\e$(3%a\e(B" (?e "\e$(3%1\e(B") (?u "\e$(3%a\e(B") (?i "\e$(3%A\e(B") (?a "\e$(3!@\e(B") (?E "\e$(3%Q\e(B"))
244 (?Y "\e$(3$_\e(B" (?a "\e$(3$_\e(B")))
245 ;;; N
246 ("\e$(3"`\e(B" (?e "\e$(3"[\e(B") (?u "\e$(3"\\e(B") (?i "\e$(3"]\e(B") (?a "\e$(3"^\e(B") (?E "\e$(3"_\e(B") (?o "\e$(3"a\e(B")
247 (?W "\e$(3"b\e(B" (?a "\e$(3"b\e(B")
248 (?e "\e$(3"`%n\e(B") (?u "\e$(3"`%r\e(B") (?i "\e$(3"`%o\e(B") (?E "\e$(3"`%q\e(B")))
249 ;;; O
250 ("\e$(3"i\e(B" (?2 "\e$(3#;\e(B"))
251 ;;; P
252 ("\e$(3$<\e(B" (?e "\e$(3$7\e(B") (?u "\e$(3$8\e(B") (?i "\e$(3$9\e(B") (?a "\e$(3$:\e(B") (?E "\e$(3$;\e(B") (?o "\e$(3$=\e(B")
253 (?W "\e$(3$>\e(B" (?a "\e$(3$>\e(B")
254 (?e "\e$(3$<%n\e(B") (?u "\e$(3$<%r\e(B") (?i "\e$(3$<%o\e(B") (?E "\e$(3$<%q\e(B")))
255 ;;; Q
256 ("\e$(3!v\e(B" (?e "\e$(3!q\e(B") (?u "\e$(3!r\e(B") (?i "\e$(3!s\e(B") (?a "\e$(3!t\e(B") (?E "\e$(3!u\e(B") (?o "\e$(3!w\e(B")
257 (?W "\e$(3!~\e(B" (?e "\e$(3!y\e(B") (?u "\e$(3!~\e(B") (?i "\e$(3!{\e(B") (?a "\e$(3!|\e(B") (?E "\e$(3!}\e(B")))
258 ;;; R
259 ("\e$(3!N\e(B" (?e "\e$(3!I\e(B") (?u "\e$(3!J\e(B") (?i "\e$(3!K\e(B") (?a "\e$(3!L\e(B") (?E "\e$(3!M\e(B") (?o "\e$(3!O\e(B")
260 (?W "\e$(3!P\e(B" (?a "\e$(3!P\e(B")
261 (?e "\e$(3!N%n\e(B") (?u "\e$(3!N%r\e(B") (?i "\e$(3!N%o\e(B") (?E "\e$(3!N%q\e(B"))
262 (?Y "\e$(3$`\e(B" (?a "\e$(3$`\e(B")))
263 ;;; S
264 ("\e$(3$D\e(B" (?e "\e$(3$?\e(B") (?u "\e$(3$@\e(B") (?i "\e$(3$A\e(B") (?a "\e$(3$B\e(B") (?E "\e$(3$C\e(B") (?o "\e$(3$E\e(B")
265 (?W "\e$(3$F\e(B" (?a "\e$(3$F\e(B")
266 (?e "\e$(3$D%n\e(B") (?u "\e$(3$D%r\e(B") (?i "\e$(3$D%o\e(B") (?E "\e$(3$D%q\e(B"))
267 (?2 "\e$(3$L\e(B"
268 (?e "\e$(3$G\e(B") (?u "\e$(3$H\e(B") (?i "\e$(3$I\e(B") (?a "\e$(3$J\e(B") (?E "\e$(3$K\e(B") (?o "\e$(3$M\e(B")
269 (?W "\e$(3$F\e(B" (?a "\e$(3$F\e(B")
270 (?e "\e$(3$L%n\e(B") (?u "\e$(3$L%r\e(B") (?i "\e$(3$L%o\e(B") (?E "\e$(3$L%q\e(B"))))
271 ;;; T
272 ("\e$(3$,\e(B" (?e "\e$(3$'\e(B") (?u "\e$(3$(\e(B") (?i "\e$(3$)\e(B") (?a "\e$(3$*\e(B") (?E "\e$(3$+\e(B") (?o "\e$(3$-\e(B")
273 (?W "\e$(3$.\e(B" (?a "\e$(3$.\e(B")
274 (?e "\e$(3$,%n\e(B") (?u "\e$(3$,%r\e(B") (?i "\e$(3$,%o\e(B") (?E "\e$(3$,%q\e(B")))
275 ;;; U
276 ("\e$(3"d\e(B" (?2 "\e$(3#6\e(B"))
277 ;;; V
278 ("\e$(3"0\e(B" (?e "\e$(3"+\e(B") (?u "\e$(3",\e(B") (?i "\e$(3"-\e(B") (?a "\e$(3".\e(B") (?E "\e$(3"/\e(B") (?o "\e$(3"1\e(B")
279 (?W "\e$(3"2\e(B" (?a "\e$(3"2\e(B")
280 (?e "\e$(3"0%n\e(B") (?u "\e$(3"0%r\e(B") (?i "\e$(3"0%o\e(B") (?E "\e$(3"0%q\e(B")))
281 ;;; W
282 ("\e$(3%r\e(B" (?e "\e$(3%n\e(B") (?u "\e$(3%r\e(B") (?i "\e$(3%o\e(B") (?a "\e$(3%p\e(B") (?E "\e$(3%q\e(B"))
283 ;;; X
284 ("\e$(3%N\e(B" (?e "\e$(3%I\e(B") (?u "\e$(3%J\e(B") (?i "\e$(3%K\e(B") (?a "\e$(3%L\e(B") (?E "\e$(3%M\e(B") (?o "\e$(3%O\e(B"))
285 ;;; Y
286 ("\e$(3#R\e(B" (?e "\e$(3#M\e(B") (?u "\e$(3#N\e(B") (?i "\e$(3#O\e(B") (?a "\e$(3#P\e(B") (?E "\e$(3#Q\e(B") (?o "\e$(3#S\e(B")
287 (?W "\e$(3#T\e(B" (?a "\e$(3#T\e(B")
288 (?e "\e$(3#R%n\e(B") (?u "\e$(3#R%r\e(B") (?i "\e$(3#R%o\e(B") (?E "\e$(3#R%q\e(B")))
289 ;;; Z
290 ("\e$(3#J\e(B" (?e "\e$(3#E\e(B") (?u "\e$(3#F\e(B") (?i "\e$(3#G\e(B") (?a "\e$(3#H\e(B") (?E "\e$(3#I\e(B") (?o "\e$(3#K\e(B")
291 (?W "\e$(3#L\e(B" (?a "\e$(3#L\e(B")
292 (?e "\e$(3#J%n\e(B") (?u "\e$(3#J%r\e(B") (?i "\e$(3#J%o\e(B") (?E "\e$(3#J%q\e(B")))
293 ;;; [ \ ] ^ _
294 nil nil nil nil nil
295 ;;; `
297 (?: "\e$(3$h\e(B")
298 (?? (if ethio-use-three-dot-question "\e$(3%x\e(B" "\e$(3$n\e(B"))
299 (?! "\e$(3%t\e(B")
300 (?e "\e$(3#5\e(B") (?u "\e$(3#6\e(B") (?U "\e$(3#6\e(B") (?i "\e$(3#7\e(B") (?a "\e$(3#8\e(B") (?A "\e$(3#8\e(B")
301 (?E "\e$(3#9\e(B") (?I "\e$(3#:\e(B") (?o "\e$(3#;\e(B") (?O "\e$(3#;\e(B")
302 (?g "\e$(3%^\e(B"
303 (?e "\e$(3%Y\e(B") (?u "\e$(3%Z\e(B") (?i "\e$(3%[\e(B") (?a "\e$(3%\\e(B") (?E "\e$(3%]\e(B") (?o "\e$(3%_\e(B"))
304 (?h "\e$(3"H\e(B"
305 (?e "\e$(3"C\e(B") (?u "\e$(3"D\e(B") (?i "\e$(3"E\e(B") (?a "\e$(3"F\e(B") (?E "\e$(3"G\e(B") (?o "\e$(3"I\e(B")
306 (?W "\e$(3"P\e(B" (?e "\e$(3"K\e(B") (?u "\e$(3"P\e(B") (?i "\e$(3"M\e(B") (?a "\e$(3"N\e(B") (?E "\e$(3"O\e(B")))
307 (?k "\e$(3%>\e(B"
308 (?e "\e$(3%9\e(B") (?u "\e$(3%:\e(B") (?i "\e$(3%;\e(B") (?a "\e$(3%<\e(B") (?E "\e$(3%=\e(B") (?o "\e$(3%?\e(B"))
309 (?s "\e$(3!F\e(B"
310 (?e "\e$(3!A\e(B") (?u "\e$(3!B\e(B") (?i "\e$(3!C\e(B") (?a "\e$(3!D\e(B") (?E "\e$(3!E\e(B") (?o "\e$(3!G\e(B")
311 (?W "\e$(3!H\e(B" (?a "\e$(3!H\e(B")
312 (?e "\e$(3!F%n\e(B") (?u "\e$(3!F%r\e(B") (?i "\e$(3!F%o\e(B") (?E "\e$(3!F%q\e(B")))
313 (?S "\e$(3$L\e(B"
314 (?e "\e$(3$G\e(B") (?u "\e$(3$H\e(B") (?i "\e$(3$I\e(B") (?a "\e$(3$J\e(B") (?E "\e$(3$K\e(B") (?o "\e$(3$M\e(B")
315 (?W "\e$(3$F\e(B" (?a "\e$(3$F\e(B")
316 (?e "\e$(3$L%n\e(B") (?u "\e$(3$L%r\e(B") (?i "\e$(3$L%o\e(B") (?E "\e$(3$L%q\e(B")))
317 (?q "\e$(3%.\e(B" (?e "\e$(3%)\e(B") (?u "\e$(3%*\e(B") (?i "\e$(3%+\e(B") (?a "\e$(3%,\e(B") (?E "\e$(3%-\e(B") (?o "\e$(3%/\e(B")))
318 ;;; a
319 ("\e$(3"f\e(B" (?2 "\e$(3#8\e(B"))
320 ;;; b
321 ("\e$(3"(\e(B" (?e "\e$(3"#\e(B") (?u "\e$(3"$\e(B") (?i "\e$(3"%\e(B") (?a "\e$(3"&\e(B") (?E "\e$(3"'\e(B") (?o "\e$(3")\e(B")
322 (?W "\e$(3%b\e(B" (?e "\e$(3%2\e(B") (?u "\e$(3%b\e(B") (?i "\e$(3%B\e(B") (?a "\e$(3"*\e(B") (?E "\e$(3%R\e(B")))
323 ;;; c
324 ("\e$(3"@\e(B" (?e "\e$(3";\e(B") (?u "\e$(3"<\e(B") (?i "\e$(3"=\e(B") (?a "\e$(3">\e(B") (?E "\e$(3"?\e(B") (?o "\e$(3"A\e(B")
325 (?W "\e$(3"B\e(B" (?a "\e$(3"B\e(B")
326 (?e "\e$(3"@%n\e(B") (?u "\e$(3"@%r\e(B") (?i "\e$(3"@%o\e(B") (?E "\e$(3"@%q\e(B")))
327 ;;; d
328 ("\e$(3#Z\e(B" (?e "\e$(3#U\e(B") (?u "\e$(3#V\e(B") (?i "\e$(3#W\e(B") (?a "\e$(3#X\e(B") (?E "\e$(3#Y\e(B") (?o "\e$(3#[\e(B")
329 (?W "\e$(3#\\e(B" (?a "\e$(3#\\e(B")
330 (?e "\e$(3#Z%o\e(B") (?u "\e$(3#Z%r\e(B") (?i "\e$(3#Z%p\e(B") (?E "\e$(3#Z%q\e(B")))
331 ;;; e
332 ("\e$(3"c\e(B" (?2 "\e$(3#5\e(B") (?a "\e$(3"j\e(B"))
333 ;;; f
334 ("\e$(3$T\e(B" (?e "\e$(3$O\e(B") (?u "\e$(3$P\e(B") (?i "\e$(3$Q\e(B") (?a "\e$(3$R\e(B") (?E "\e$(3$S\e(B") (?o "\e$(3$U\e(B")
335 (?W "\e$(3%d\e(B" (?e "\e$(3%4\e(B") (?u "\e$(3%d\e(B") (?i "\e$(3%D\e(B") (?a "\e$(3$V\e(B") (?E "\e$(3%T\e(B"))
336 (?Y "\e$(3$a\e(B" (?a "\e$(3$a\e(B")))
337 ;;; g
338 ("\e$(3#r\e(B" (?e "\e$(3#m\e(B") (?u "\e$(3#n\e(B") (?i "\e$(3#o\e(B") (?a "\e$(3#p\e(B") (?E "\e$(3#q\e(B") (?o "\e$(3#s\e(B")
339 (?W "\e$(3#z\e(B" (?e "\e$(3#u\e(B") (?u "\e$(3#z\e(B") (?i "\e$(3#w\e(B") (?a "\e$(3#x\e(B") (?E "\e$(3#y\e(B"))
340 (?2 "\e$(3%^\e(B" (?e "\e$(3%Y\e(B") (?u "\e$(3%Z\e(B") (?i "\e$(3%[\e(B") (?a "\e$(3%\\e(B") (?E "\e$(3%]\e(B") (?o "\e$(3%_\e(B")))
341 ;;; h
342 ("\e$(3!&\e(B" (?e "\e$(3!!\e(B") (?u "\e$(3!"\e(B") (?i "\e$(3!#\e(B") (?a "\e$(3!$\e(B") (?E "\e$(3!%\e(B") (?o "\e$(3!'\e(B")
343 (?W "\e$(3"P\e(B" (?e "\e$(3"K\e(B") (?u "\e$(3"P\e(B") (?i "\e$(3"M\e(B") (?a "\e$(3"N\e(B") (?E "\e$(3"O\e(B"))
344 (?2 "\e$(3"H\e(B" (?e "\e$(3"C\e(B") (?u "\e$(3"D\e(B") (?i "\e$(3"E\e(B") (?a "\e$(3"F\e(B") (?E "\e$(3"G\e(B") (?o "\e$(3"I\e(B")
345 (?W "\e$(3"P\e(B" (?e "\e$(3"K\e(B") (?u "\e$(3"P\e(B") (?i "\e$(3"M\e(B") (?a "\e$(3"N\e(B") (?E "\e$(3"O\e(B"))))
346 ;;; i
347 ("\e$(3"e\e(B" (?2 "\e$(3#7\e(B"))
348 ;;; j
349 ("\e$(3#j\e(B" (?e "\e$(3#e\e(B") (?u "\e$(3#f\e(B") (?i "\e$(3#g\e(B") (?a "\e$(3#h\e(B") (?E "\e$(3#i\e(B") (?o "\e$(3#k\e(B")
350 (?W "\e$(3#l\e(B" (?a "\e$(3#l\e(B")
351 (?e "\e$(3#j%n\e(B") (?u "\e$(3#j%r\e(B") (?i "\e$(3#j%o\e(B") (?E "\e$(3#j%q\e(B")))
352 ;;; k
353 ("\e$(3"p\e(B" (?e "\e$(3"k\e(B") (?u "\e$(3"l\e(B") (?i "\e$(3"m\e(B") (?a "\e$(3"n\e(B") (?E "\e$(3"o\e(B") (?o "\e$(3"q\e(B")
354 (?W "\e$(3"x\e(B" (?e "\e$(3"s\e(B") (?u "\e$(3"x\e(B") (?i "\e$(3"u\e(B") (?a "\e$(3"v\e(B") (?E "\e$(3"w\e(B"))
355 (?2 "\e$(3%>\e(B" (?e "\e$(3%9\e(B") (?u "\e$(3%:\e(B") (?i "\e$(3%;\e(B") (?a "\e$(3%<\e(B") (?E "\e$(3%=\e(B") (?o "\e$(3%?\e(B")))
356 ;;; l
357 ("\e$(3!.\e(B" (?e "\e$(3!)\e(B") (?u "\e$(3!*\e(B") (?i "\e$(3!+\e(B") (?a "\e$(3!,\e(B") (?E "\e$(3!-\e(B") (?o "\e$(3!/\e(B")
358 (?W "\e$(3!0\e(B" (?a "\e$(3!0\e(B")
359 (?e "\e$(3!.%n\e(B") (?u "\e$(3!.%r\e(B") (?i "\e$(3!.%o\e(B") (?E "\e$(3!.%q\e(B")))
360 ;;; m
361 ("\e$(3!>\e(B" (?e "\e$(3!9\e(B") (?u "\e$(3!:\e(B") (?i "\e$(3!;\e(B") (?a "\e$(3!<\e(B") (?E "\e$(3!=\e(B") (?o "\e$(3!?\e(B")
362 (?W "\e$(3%a\e(B" (?e "\e$(3%1\e(B") (?u "\e$(3%a\e(B") (?i "\e$(3%A\e(B") (?a "\e$(3!@\e(B") (?E "\e$(3%Q\e(B"))
363 (?Y "\e$(3$_\e(B" (?a "\e$(3$_\e(B")))
364 ;;; n
365 ("\e$(3"X\e(B" (?e "\e$(3"S\e(B") (?u "\e$(3"T\e(B") (?i "\e$(3"U\e(B") (?a "\e$(3"V\e(B") (?E "\e$(3"W\e(B") (?o "\e$(3"Y\e(B")
366 (?W "\e$(3"Z\e(B" (?a "\e$(3"Z\e(B")
367 (?e "\e$(3"X%n\e(B") (?u "\e$(3"X%r\e(B") (?i "\e$(3"X%o\e(B") (?E "\e$(3"X%q\e(B")))
368 ;;; o
369 ("\e$(3"i\e(B" (?2 "\e$(3#;\e(B"))
370 ;;; p
371 ("\e$(3$\\e(B" (?e "\e$(3$W\e(B") (?u "\e$(3$X\e(B") (?i "\e$(3$Y\e(B") (?a "\e$(3$Z\e(B") (?E "\e$(3$[\e(B") (?o "\e$(3$]\e(B")
372 (?W "\e$(3%e\e(B" (?e "\e$(3%5\e(B") (?u "\e$(3%e\e(B") (?i "\e$(3%E\e(B") (?a "\e$(3$^\e(B") (?E "\e$(3%U\e(B")))
373 ;;; q
374 ("\e$(3!f\e(B" (?e "\e$(3!a\e(B") (?u "\e$(3!b\e(B") (?i "\e$(3!c\e(B") (?a "\e$(3!d\e(B") (?E "\e$(3!e\e(B") (?o "\e$(3!g\e(B")
375 (?W "\e$(3!n\e(B" (?e "\e$(3!i\e(B") (?u "\e$(3!n\e(B") (?i "\e$(3!k\e(B") (?a "\e$(3!l\e(B") (?E "\e$(3!m\e(B"))
376 (?2 "\e$(3%.\e(B" (?e "\e$(3%)\e(B") (?u "\e$(3%*\e(B") (?i "\e$(3%+\e(B") (?a "\e$(3%,\e(B") (?E "\e$(3%-\e(B") (?o "\e$(3%/\e(B")))
377 ;;; r
378 ("\e$(3!N\e(B" (?e "\e$(3!I\e(B") (?u "\e$(3!J\e(B") (?i "\e$(3!K\e(B") (?a "\e$(3!L\e(B") (?E "\e$(3!M\e(B") (?o "\e$(3!O\e(B")
379 (?W "\e$(3!P\e(B" (?a "\e$(3!P\e(B")
380 (?e "\e$(3!N%n\e(B") (?u "\e$(3!N%r\e(B") (?i "\e$(3!N%o\e(B") (?E "\e$(3!N%q\e(B"))
381 (?Y "\e$(3$`\e(B" (?a "\e$(3$`\e(B")))
382 ;;; s
383 ("\e$(3!V\e(B" (?e "\e$(3!Q\e(B") (?u "\e$(3!R\e(B") (?i "\e$(3!S\e(B") (?a "\e$(3!T\e(B") (?E "\e$(3!U\e(B") (?o "\e$(3!W\e(B")
384 (?W "\e$(3!X\e(B" (?a "\e$(3!X\e(B")
385 (?e "\e$(3!V%n\e(B") (?u "\e$(3!V%r\e(B") (?i "\e$(3!V%o\e(B") (?E "\e$(3!V%q\e(B"))
386 (?2 "\e$(3!F\e(B" (?e "\e$(3!A\e(B") (?u "\e$(3!B\e(B") (?i "\e$(3!C\e(B") (?a "\e$(3!D\e(B") (?E "\e$(3!E\e(B") (?o "\e$(3!G\e(B")
387 (?W "\e$(3!H\e(B" (?a "\e$(3!H\e(B")
388 (?e "\e$(3!F%n\e(B") (?u "\e$(3!F%r\e(B") (?i "\e$(3!F%o\e(B") (?E "\e$(3!F%q\e(B"))))
389 ;;; t
390 ("\e$(3"8\e(B" (?e "\e$(3"3\e(B") (?u "\e$(3"4\e(B") (?i "\e$(3"5\e(B") (?a "\e$(3"6\e(B") (?E "\e$(3"7\e(B") (?o "\e$(3"9\e(B")
391 (?W "\e$(3":\e(B" (?a "\e$(3":\e(B")
392 (?e "\e$(3"8%n\e(B") (?u "\e$(3"8%r\e(B") (?i "\e$(3"8%o\e(B") (?E "\e$(3"8%q\e(B")))
393 ;;; u
394 ("\e$(3"d\e(B" (?2 "\e$(3#6\e(B"))
395 ;;; v
396 ("\e$(3"0\e(B" (?e "\e$(3"+\e(B") (?u "\e$(3",\e(B") (?i "\e$(3"-\e(B") (?a "\e$(3".\e(B") (?E "\e$(3"/\e(B") (?o "\e$(3"1\e(B")
397 (?W "\e$(3"2\e(B" (?a "\e$(3"2\e(B")
398 (?e "\e$(3"0%n\e(B") (?u "\e$(3"0%r\e(B") (?i "\e$(3"0%o\e(B") (?E "\e$(3"0%q\e(B")))
399 ;;; w
400 ("\e$(3#2\e(B" (?e "\e$(3#-\e(B") (?u "\e$(3#.\e(B") (?i "\e$(3#/\e(B") (?a "\e$(3#0\e(B") (?E "\e$(3#1\e(B") (?o "\e$(3#3\e(B")
401 (?W "\e$(3%p\e(B" (?e "\e$(3%n\e(B") (?u "\e$(3%r\e(B") (?i "\e$(3%o\e(B") (?a "\e$(3%p\e(B") (?E "\e$(3%q\e(B")))
402 ;;; x
403 ("\e$(3!^\e(B" (?e "\e$(3!Y\e(B") (?u "\e$(3!Z\e(B") (?i "\e$(3![\e(B") (?a "\e$(3!\\e(B") (?E "\e$(3!]\e(B") (?o "\e$(3!_\e(B")
404 (?W "\e$(3!`\e(B" (?a "\e$(3!`\e(B")
405 (?e "\e$(3!^%n\e(B") (?u "\e$(3!^%r\e(B") (?i "\e$(3!^%o\e(B") (?E "\e$(3!^%q\e(B")))
406 ;;; y
407 ("\e$(3#R\e(B" (?e "\e$(3#M\e(B") (?u "\e$(3#N\e(B") (?i "\e$(3#O\e(B") (?a "\e$(3#P\e(B") (?E "\e$(3#Q\e(B") (?o "\e$(3#S\e(B")
408 (?W "\e$(3#T\e(B" (?a "\e$(3#T\e(B")
409 (?e "\e$(3#R%n\e(B") (?u "\e$(3#R%r\e(B") (?i "\e$(3#R%o\e(B") (?E "\e$(3#R%q\e(B")))
410 ;;; z
411 ("\e$(3#B\e(B" (?e "\e$(3#=\e(B") (?u "\e$(3#>\e(B") (?i "\e$(3#?\e(B") (?a "\e$(3#@\e(B") (?E "\e$(3#A\e(B") (?o "\e$(3#C\e(B")
412 (?W "\e$(3#D\e(B" (?a "\e$(3#D\e(B")
413 (?e "\e$(3#B%n\e(B") (?u "\e$(3#B%r\e(B") (?i "\e$(3#B%o\e(B") (?E "\e$(3#B%q\e(B")))
414 ;;; { | } ~ DEL
415 nil nil nil nil nil
418 ;;;###autoload
419 (defun ethio-sera-to-fidel-region (beg end &optional secondary force)
420 "Convert the characters in region from SERA to FIDEL.
421 The variable `ethio-primary-language' specifies the primary language
422 and `ethio-secondary-language' specifies the secondary.
424 If the 3rd parameter SECONDARY is given and non-nil, assume the region
425 begins begins with the secondary language; otherwise with the primary
426 language.
428 If the 4th parameter FORCE is given and non-nil, perform conversion
429 even if the buffer is read-only.
431 See also the descriptions of the variables
432 `ethio-use-colon-for-colon' and
433 `ethio-use-three-dot-question'."
435 (interactive "r\nP")
436 (save-restriction
437 (narrow-to-region beg end)
438 (ethio-sera-to-fidel-buffer secondary force)))
440 ;;;###autoload
441 (defun ethio-sera-to-fidel-buffer (&optional secondary force)
442 "Convert the current buffer from SERA to FIDEL.
444 The variable `ethio-primary-language' specifies the primary
445 language and `ethio-secondary-language' specifies the secondary.
447 If the 1st optional parameter SECONDARY is non-nil, assume the buffer
448 begins with the secondary language; otherwise with the primary
449 language.
451 If the 2nd optional parametr FORCE is non-nil, perform conversion even if the
452 buffer is read-only.
454 See also the descriptions of the variables
455 `ethio-use-colon-for-colon' and
456 `ethio-use-three-dot-question'."
458 (interactive "P")
460 (if (and buffer-read-only
461 (not force)
462 (not (y-or-n-p "Buffer is read-only. Force to convert? ")))
463 (error ""))
465 (let ((ethio-primary-language ethio-primary-language)
466 (ethio-secondary-language ethio-secondary-language)
467 (ethio-use-colon-for-colon ethio-use-colon-for-colon)
468 (ethio-use-three-dot-question ethio-use-three-dot-question)
469 ;; The above four variables may be changed temporary
470 ;; by tilde escapes during conversion. So we bind them to other
471 ;; variables but of the same names.
472 (buffer-read-only nil)
473 (case-fold-search nil)
474 current-language
475 next-language)
477 (setq current-language
478 (if secondary
479 ethio-secondary-language
480 ethio-primary-language))
482 (goto-char (point-min))
484 (while (not (eobp))
485 (setq next-language
486 (cond
487 ((eq current-language 'english)
488 (ethio-sera-to-fidel-english))
489 ((eq current-language 'amharic)
490 (ethio-sera-to-fidel-ethio 'amharic))
491 ((eq current-language 'tigrigna)
492 (ethio-sera-to-fidel-ethio 'tigrigna))
493 (t ; we don't know what to do
494 (ethio-sera-to-fidel-english))))
496 (setq current-language
497 (cond
499 ;; when language tag is explicitly specified
500 ((not (eq next-language 'toggle))
501 next-language)
503 ;; found a toggle in a primary language section
504 ((eq current-language ethio-primary-language)
505 ethio-secondary-language)
507 ;; found a toggle in a secondary, third, fourth, ...
508 ;; language section
510 ethio-primary-language))))
512 ;; If ethio-implicit-period-conversion is non-nil, the
513 ;; Ethiopic dot "\e$(3%u\e(B" at the end of an Ethiopic sentence is
514 ;; replaced with the Ethiopic full stop "\e$(3$i\e(B".
515 (if ethio-implicit-period-conversion
516 (progn
517 (goto-char (point-min))
518 (while (re-search-forward "\\([\e$(3!!\e(B-\e$(3$a%)\e(B-\e$(3%e%n\e(B-\e$(3%r%s\e(B]\\)\e$(3%u\e(B\\([ \t]\\)"
519 nil t)
520 (replace-match "\\1\e$(3$i\e(B\\2"))
521 (goto-char (point-min))
522 (while (re-search-forward "\\([\e$(3!!\e(B-\e$(3$a%)\e(B-\e$(3%e%n\e(B-\e$(3%r%s\e(B]\\)\e$(3%u\e(B$" nil t)
523 (replace-match "\\1\e$(3$i\e(B"))))
525 ;; gemination
526 (goto-char (point-min))
527 (while (re-search-forward "\\ce\e$(3%s\e(B" nil 0)
528 (compose-region
529 (save-excursion (backward-char 2) (point))
530 (point)))
533 (defun ethio-sera-to-fidel-english nil
534 "Handle English section in SERA to FIDEL conversion.
535 Conversion stops when a language switch is found. Then delete that
536 switch and return the name of the new language as a symbol."
537 (let ((new-language nil))
539 (while (and (not (eobp)) (null new-language))
540 (cond
542 ;; if no more "\", nothing to do.
543 ((not (search-forward "\\" nil 0)))
545 ;; hereafter point is put after a "\".
546 ;; first delete that "\", then check the following chars
548 ;; "\\" : leave the second "\"
549 ((progn
550 (delete-backward-char 1)
551 (= (following-char) ?\\ ))
552 (forward-char 1))
554 ;; "\ " : delete the following " "
555 ((= (following-char) 32)
556 (delete-char 1)
557 (setq new-language 'toggle))
559 ;; a language flag
560 ((setq new-language (ethio-process-language-flag)))
562 ;; just a "\" : not special sequence.
564 (setq new-language 'toggle))))
566 new-language))
568 (defun ethio-sera-to-fidel-ethio (lang)
569 "Handle Ethiopic section in SERA to FIDEL conversion.
570 Conversion stops when a language switch is found. Then delete that
571 switch and return the name of the new language as a symbol.
573 The parameter LANG (symbol, either `amharic' or `tigrigna') affects
574 the conversion of \"a\"."
576 (let ((new-language nil)
577 (verbatim nil)
578 start table table2 ch)
580 (setcar (aref ethio-sera-to-fidel-table ?a)
581 (if (eq lang 'tigrigna) "\e$(3"f\e(B" "\e$(3"c\e(B"))
583 (while (and (not (eobp)) (null new-language))
584 (setq ch (following-char))
585 (cond
587 ;; skip from "<" to ">" (or from "&" to ";") if in w3-mode
588 ((and (boundp 'sera-being-called-by-w3)
589 sera-being-called-by-w3
590 (or (= ch ?<) (= ch ?&)))
591 (search-forward (if (= ch ?<) ">" ";")
592 nil 0))
594 ;; leave non-ASCII characters as they are
595 ((>= ch 128)
596 (forward-char 1))
598 ;; ethiopic digits
599 ((looking-at "`[1-9][0-9]*")
600 (delete-char 1)
601 (ethio-convert-digit))
603 ;; if not seeing a "\", do sera to fidel conversion
604 ((/= ch ?\\ )
605 (setq start (point))
606 (forward-char 1)
607 (setq table (aref ethio-sera-to-fidel-table ch))
608 (while (setq table2 (cdr (assoc (following-char) table)))
609 (setq table table2)
610 (forward-char 1))
611 (if (setq ch (car table))
612 (progn
613 (delete-region start (point))
614 (if (stringp ch)
615 (insert ch)
616 (insert (eval ch))))))
618 ;; if control reaches here, we must be looking at a "\"
620 ;; verbatim mode
621 (verbatim
622 (if (looking-at "\\\\~! ?")
624 ;; "\~!" or "\~! ". switch to non-verbatim mode
625 (progn
626 (replace-match "")
627 (setq verbatim nil))
629 ;; "\" but not "\~!" nor "\~! ". skip the current "\".
630 (forward-char 1)))
632 ;; hereafter, non-verbatim mode and looking at a "\"
633 ;; first delete that "\", then check the following chars.
635 ;; "\ " : delete the following " "
636 ((progn
637 (delete-char 1)
638 (setq ch (following-char))
639 (= ch 32))
640 (delete-char 1)
641 (setq new-language 'toggle))
643 ;; "\~!" or "\~! " : switch to verbatim mode
644 ((looking-at "~! ?")
645 (replace-match "")
646 (setq verbatim t))
648 ;; a language flag
649 ((setq new-language (ethio-process-language-flag)))
651 ;; "\~" but not "\~!" nor a language flag
652 ((= ch ?~)
653 (delete-char 1)
654 (ethio-tilde-escape))
656 ;; ASCII punctuation escape. skip
657 ((looking-at "\\(,\\|\\.\\|;\\|:\\|'\\|`\\|\?\\|\\\\\\)+")
658 (goto-char (match-end 0)))
660 ;; "\", but not special sequence
662 (setq new-language 'toggle))))
664 new-language))
666 (defun ethio-process-language-flag nil
667 "Process a language flag of the form \"~lang\" or \"~lang1~lang2\".
669 If looking at \"~lang1~lang2\", set `ethio-primary-language' and
670 `ethio-une-secondary-language' based on \"lang1\" and \"lang2\".
671 Then delete the language flag \"~lang1~lang2\" from the buffer.
672 Return value is the new primary language.
674 If looking at \"~lang\", delete that language flag \"~lang\" from the
675 buffer and return that language. In this case
676 `ethio-primary-language' and `ethio-uni-secondary-language'
677 are left unchanged.
679 If an unsupported language flag is found, just return nil without
680 changing anything."
682 (let (lang1 lang2)
683 (cond
685 ;; ~lang1~lang2
686 ((and (looking-at
687 "~\\([a-z][a-z][a-z]?\\)~\\([a-z][a-z][a-z]?\\)[ \t\n\\]")
688 (setq lang1
689 (ethio-flag-to-language
690 (buffer-substring (match-beginning 1) (match-end 1))))
691 (setq lang2
692 (ethio-flag-to-language
693 (buffer-substring (match-beginning 2) (match-end 2)))))
694 (setq ethio-primary-language lang1
695 ethio-secondary-language lang2)
696 (delete-region (point) (match-end 2))
697 (if (= (following-char) 32)
698 (delete-char 1))
699 ethio-primary-language)
701 ;; ~lang
702 ((and (looking-at "~\\([a-z][a-z][a-z]?\\)[ \t\n\\]")
703 (setq lang1
704 (ethio-flag-to-language
705 (buffer-substring (match-beginning 1) (match-end 1)))))
706 (delete-region (point) (match-end 1))
707 (if (= (following-char) 32)
708 (delete-char 1))
709 lang1)
711 ;; otherwise
713 nil))))
715 (defun ethio-tilde-escape nil
716 "Handle a SERA tilde escape in Ethiopic section and delete it.
717 Delete the escape even it is not recognised."
719 (let ((p (point)) command)
720 (skip-chars-forward "^ \t\n\\\\")
721 (setq command (buffer-substring p (point)))
722 (delete-region p (point))
723 (if (= (following-char) 32)
724 (delete-char 1))
726 (cond
728 ;; \~-:
729 ((string= command "-:")
730 (setq ethio-use-colon-for-colon t))
732 ;; \~`:
733 ((string= command "`:")
734 (setq ethio-use-colon-for-colon nil))
736 ;; \~?
737 ((string= command "?")
738 (setq ethio-use-three-dot-question nil))
740 ;; \~`|
741 ((string= command "`|")
742 (setq ethio-use-three-dot-question t))
744 ;; \~e
745 ((string= command "e")
746 (insert "\e$(3%j\e(B"))
748 ;; \~E
749 ((string= command "E")
750 (insert "\e$(3%k\e(B"))
752 ;; \~a
753 ((string= command "a")
754 (insert "\e$(3%l\e(B"))
756 ;; \~A
757 ((string= command "A")
758 (insert "\e$(3%m\e(B"))
760 ;; \~X
761 ((string= command "X")
762 (insert "\e$(3%i\e(B"))
764 ;; unsupported tilde escape
766 nil))))
768 (defun ethio-flag-to-language (flag)
769 (cond
770 ((or (string= flag "en") (string= flag "eng")) 'english)
771 ((or (string= flag "ti") (string= flag "tir")) 'tigrigna)
772 ((or (string= flag "am") (string= flag "amh")) 'amharic)
773 (t nil)))
775 (defun ethio-convert-digit nil
776 "Convert Arabic digits to Ethiopic digits."
777 (let (ch z)
778 (while (and (>= (setq ch (following-char)) ?1)
779 (<= ch ?9))
780 (delete-char 1)
782 ;; count up following zeros
783 (setq z 0)
784 (while (= (following-char) ?0)
785 (delete-char 1)
786 (setq z (1+ z)))
788 (cond
790 ;; first digit is 10, 20, ..., or 90
791 ((= (mod z 2) 1)
792 (insert (aref [?\e$(3$y\e(B ?\e$(3$z\e(B ?\e$(3${\e(B ?\e$(3$|\e(B ?\e$(3$}\e(B ?\e$(3$~\e(B ?\e$(3%!\e(B ?\e$(3%"\e(B ?\e$(3%#\e(B] (- ch ?1)))
793 (setq z (1- z)))
795 ;; first digit is 2, 3, ..., or 9
796 ((/= ch ?1)
797 (insert (aref [?\e$(3$q\e(B ?\e$(3$r\e(B ?\e$(3$s\e(B ?\e$(3$t\e(B ?\e$(3$u\e(B ?\e$(3$v\e(B ?\e$(3$w\e(B ?\e$(3$x\e(B] (- ch ?2))))
799 ;; single 1
800 ((= z 0)
801 (insert "\e$(3$p\e(B")))
803 ;; 100
804 (if (= (mod z 4) 2)
805 (insert "\e$(3%$\e(B"))
807 ;; 10000
808 (insert-char ?\e$(3%%\e(B (/ z 4)))))
810 ;;;###autoload
811 (defun ethio-sera-to-fidel-mail-or-marker (&optional arg)
812 "Execute ethio-sera-to-fidel-mail or ethio-sera-to-fidel-marker depending on the current major mode.
813 If in rmail-mode or in mail-mode, execute the former; otherwise latter."
815 (interactive "P")
816 (if (or (eq major-mode 'rmail-mode)
817 (eq major-mode 'mail-mode))
818 (ethio-sera-to-fidel-mail (prefix-numeric-value arg))
819 (ethio-sera-to-fidel-marker arg)))
821 ;;;###autoload
822 (defun ethio-sera-to-fidel-mail (&optional arg)
823 "Convert SERA to FIDEL to read/write mail and news.
825 If the buffer contains the markers \"<sera>\" and \"</sera>\",
826 convert the segments between them into FIDEL.
828 If invoked interactively and there is no marker, convert the subject field
829 and the body into FIDEL using `ethio-sera-to-fidel-region'."
831 (interactive "p")
832 (let ((buffer-read-only nil)
833 border)
834 (save-excursion
836 ;; follow RFC822 rules instead of looking for a fixed separator
837 (rfc822-goto-eoh)
838 (forward-line 1)
839 (setq border (point))
841 ;; note that the point is placed at the border
842 (if (or (re-search-forward "^<sera>$" nil t)
843 (progn
844 (goto-char (point-min))
845 (re-search-forward "^Subject: <sera>" border t)))
847 ;; there are markers
848 (progn
849 ;; we start with the body so that the border will not change
850 ;; use "^<sera>\n" instead of "^<sera>$" not to leave a blank line
851 (goto-char border)
852 (while (re-search-forward "^<sera>\n" nil t)
853 (replace-match "")
854 (ethio-sera-to-fidel-region
855 (point)
856 (progn
857 (if (re-search-forward "^</sera>\n" nil 0)
858 (replace-match ""))
859 (point))))
860 ;; now process the subject
861 (goto-char (point-min))
862 (if (re-search-forward "^Subject: <sera>" border t)
863 (ethio-sera-to-fidel-region
864 (progn (delete-backward-char 6) (point))
865 (progn
866 (if (re-search-forward "</sera>$" (line-end-position) 0)
867 (replace-match ""))
868 (point)))))
870 ;; in case there are no marks but invoked interactively
871 (if arg
872 (progn
873 (ethio-sera-to-fidel-region border (point-max))
874 (goto-char (point-min))
875 (if (re-search-forward "^Subject: " border t)
876 (ethio-sera-to-fidel-region (point) (line-end-position))))))
878 ;; adjust the rmail marker
879 (if (eq major-mode 'rmail-mode)
880 (set-marker
881 (aref rmail-message-vector (1+ rmail-current-message))
882 (point-max))))))
884 ;;;###autoload
885 (defun ethio-sera-to-fidel-marker (&optional force)
886 "Convert the regions surrounded by \"<sera>\" and \"</sera>\" from SERA to FIDEL.
887 Assume that each region begins with `ethio-primary-language'.
888 The markers \"<sera>\" and \"</sera>\" themselves are not deleted."
889 (interactive "P")
890 (if (and buffer-read-only
891 (not force)
892 (not (y-or-n-p "Buffer is read-only. Force to convert? ")))
893 (error ""))
894 (save-excursion
895 (goto-char (point-min))
896 (while (re-search-forward "<sera>" nil t)
897 (ethio-sera-to-fidel-region
898 (point)
899 (if (re-search-forward "</sera>" nil t)
900 (match-beginning 0)
901 (point-max))
903 'force))))
906 ;; FIDEL to SERA
909 (defconst ethio-fidel-to-sera-map
910 [ "he" "hu" "hi" "ha" "hE" "h" "ho" "" ;; 0 - 7
911 "le" "lu" "li" "la" "lE" "l" "lo" "lWa" ;; 8
912 "He" "Hu" "Hi" "Ha" "HE" "H" "Ho" "HWa" ;; 16
913 "me" "mu" "mi" "ma" "mE" "m" "mo" "mWa" ;; 24
914 "`se" "`su" "`si" "`sa" "`sE" "`s" "`so" "`sWa" ;; 32
915 "re" "ru" "ri" "ra" "rE" "r" "ro" "rWa" ;; 40
916 "se" "su" "si" "sa" "sE" "s" "so" "sWa" ;; 48
917 "xe" "xu" "xi" "xa" "xE" "x" "xo" "xWa" ;; 56
918 "qe" "qu" "qi" "qa" "qE" "q" "qo" "" ;; 64
919 "qWe" "" "qWi" "qWa" "qWE" "qW'" "" "" ;; 72
920 "Qe" "Qu" "Qi" "Qa" "QE" "Q" "Qo" "" ;; 80
921 "QWe" "" "QWi" "QWa" "QWE" "QW'" "" "" ;; 88
922 "be" "bu" "bi" "ba" "bE" "b" "bo" "bWa" ;; 96
923 "ve" "vu" "vi" "va" "vE" "v" "vo" "vWa" ;; 104
924 "te" "tu" "ti" "ta" "tE" "t" "to" "tWa" ;; 112
925 "ce" "cu" "ci" "ca" "cE" "c" "co" "cWa" ;; 120
926 "`he" "`hu" "`hi" "`ha" "`hE" "`h" "`ho" "" ;; 128
927 "hWe" "" "hWi" "hWa" "hWE" "hW'" "" "" ;; 136
928 "ne" "nu" "ni" "na" "nE" "n" "no" "nWa" ;; 144
929 "Ne" "Nu" "Ni" "Na" "NE" "N" "No" "NWa" ;; 152
930 "e" "u" "i" "A" "E" "I" "o" "ea" ;; 160
931 "ke" "ku" "ki" "ka" "kE" "k" "ko" "" ;; 168
932 "kWe" "" "kWi" "kWa" "kWE" "kW'" "" "" ;; 176
933 "Ke" "Ku" "Ki" "Ka" "KE" "K" "Ko" "" ;; 184
934 "KWe" "" "KWi" "KWa" "KWE" "KW'" "" "" ;; 192
935 "we" "wu" "wi" "wa" "wE" "w" "wo" "" ;; 200
936 "`e" "`u" "`i" "`a" "`E" "`I" "`o" "" ;; 208
937 "ze" "zu" "zi" "za" "zE" "z" "zo" "zWa" ;; 216
938 "Ze" "Zu" "Zi" "Za" "ZE" "Z" "Zo" "ZWa" ;; 224
939 "ye" "yu" "yi" "ya" "yE" "y" "yo" "yWa" ;; 232
940 "de" "du" "di" "da" "dE" "d" "do" "dWa" ;; 240
941 "De" "Du" "Di" "Da" "DE" "D" "Do" "DWa" ;; 248
942 "je" "ju" "ji" "ja" "jE" "j" "jo" "jWa" ;; 256
943 "ge" "gu" "gi" "ga" "gE" "g" "go" "" ;; 264
944 "gWe" "" "gWi" "gWa" "gWE" "gW'" "" "" ;; 272
945 "Ge" "Gu" "Gi" "Ga" "GE" "G" "Go" "GWa" ;; 280
946 "Te" "Tu" "Ti" "Ta" "TE" "T" "To" "TWa" ;; 288
947 "Ce" "Cu" "Ci" "Ca" "CE" "C" "Co" "CWa" ;; 296
948 "Pe" "Pu" "Pi" "Pa" "PE" "P" "Po" "PWa" ;; 304
949 "Se" "Su" "Si" "Sa" "SE" "S" "So" "SWa" ;; 312
950 "`Se" "`Su" "`Si" "`Sa" "`SE" "`S" "`So" "" ;; 320
951 "fe" "fu" "fi" "fa" "fE" "f" "fo" "fWa" ;; 328
952 "pe" "pu" "pi" "pa" "pE" "p" "po" "pWa" ;; 336
953 "mYa" "rYa" "fYa" "" "" "" "" "" ;; 344
954 " " " : " "::" "," ";" "-:" ":-" "`?" ;; 352
955 ":|:" "1" "2" "3" "4" "5" "6" "7" ;; 360
956 "8" "9" "10" "20" "30" "40" "50" "60" ;; 368
957 "70" "80" "90" "100" "10000" "" "" "" ;; 376
958 "`qe" "`qu" "`qi" "`qa" "`qE" "`q" "`qo" "" ;; 384
959 "mWe" "bWe" "GWe" "fWe" "pWe" "" "" "" ;; 392
960 "`ke" "`ku" "`ki" "`ka" "`kE" "`k" "`ko" "" ;; 400
961 "mWi" "bWi" "GWi" "fWi" "pWi" "" "" "" ;; 408
962 "Xe" "Xu" "Xi" "Xa" "XE" "X" "Xo" "" ;; 416
963 "mWE" "bWE" "GWE" "fWE" "pWE" "" "" "" ;; 424
964 "`ge" "`gu" "`gi" "`ga" "`gE" "`g" "`go" "" ;; 432
965 "mW'" "bW'" "GW'" "fW'" "pW'" "" "" "" ;; 440
966 "\\~X " "\\~e " "\\~E " "\\~a " "\\~A " "wWe" "wWi" "wWa" ;; 448
967 "wWE" "wW'" "''" "`!" "." "<<" ">>" "?" ]) ;; 456
969 (defun ethio-prefer-amharic-p nil
970 (or (eq ethio-primary-language 'amharic)
971 (and (not (eq ethio-primary-language 'tigrigna))
972 (eq ethio-secondary-language 'amharic))))
974 (defun ethio-language-to-flag (lang)
975 (cond
976 ((eq lang 'english) "eng")
977 ((eq lang 'tigrigna) "tir")
978 ((eq lang 'amharic) "amh")
979 (t "")))
981 ;;;###autoload
982 (defun ethio-fidel-to-sera-region (begin end &optional secondary force)
983 "Replace all the FIDEL characters in the region to the SERA format.
984 The variable `ethio-primary-language' specifies the primary
985 language and `ethio-secondary-language' specifies the secondary.
987 If the 3dr parameter SECONDARY is given and non-nil, try to convert
988 the region so that it begins in the secondary language; otherwise with
989 the primary language.
991 If the 4th parameter FORCE is given and non-nil, convert even if the
992 buffer is read-only.
994 See also the descriptions of the variables
995 `ethio-use-colon-for-colon', `ethio-use-three-dot-question',
996 `ethio-quote-vowel-always' and `ethio-numeric-reduction'."
998 (interactive "r\nP")
999 (save-restriction
1000 (narrow-to-region begin end)
1001 (ethio-fidel-to-sera-buffer secondary force)))
1003 ;;;###autoload
1004 (defun ethio-fidel-to-sera-buffer (&optional secondary force)
1005 "Replace all the FIDEL characters in the current buffer to the SERA format.
1006 The variable `ethio-primary-language' specifies the primary
1007 language and `ethio-secondary-language' specifies the secondary.
1009 If the 1st optional parameter SECONDARY is non-nil, try to convert the
1010 region so that it begins in the secondary language; otherwise with the
1011 primary language.
1013 If the 2nd optional parameter FORCE is non-nil, convert even if the
1014 buffer is read-only.
1016 See also the descriptions of the variables
1017 `ethio-use-colon-for-colon', `ethio-use-three-dot-question',
1018 `ethio-quote-vowel-always' and `ethio-numeric-reduction'."
1020 (interactive "P")
1021 (if (and buffer-read-only
1022 (not force)
1023 (not (y-or-n-p "Buffer is read-only. Force to convert? ")))
1024 (error ""))
1026 (let ((buffer-read-only nil)
1027 (case-fold-search nil)
1028 (lonec nil) ;; t means previous char was a lone consonant
1029 (fidel nil) ;; t means previous char was a FIDEL
1030 (digit nil) ;; t means previous char was an Ethiopic digit
1031 (flag (if (ethio-prefer-amharic-p) "\\~amh " "\\~tir "))
1032 mode ch)
1034 ;; user's preference in transcription
1035 (if ethio-use-colon-for-colon
1036 (progn
1037 (aset ethio-fidel-to-sera-map 353 "`:")
1038 (aset ethio-fidel-to-sera-map 357 ":"))
1039 (aset ethio-fidel-to-sera-map 353 " : ")
1040 (aset ethio-fidel-to-sera-map 357 "-:"))
1042 (if ethio-use-three-dot-question
1043 (progn
1044 (aset ethio-fidel-to-sera-map 359 "?")
1045 (aset ethio-fidel-to-sera-map 463 "`?"))
1046 (aset ethio-fidel-to-sera-map 359 "`?")
1047 (aset ethio-fidel-to-sera-map 463 "?"))
1049 (mapcar
1050 '(lambda (x)
1051 (aset (aref ethio-fidel-to-sera-map x)
1053 (if ethio-W-sixth-always ?' ?u)))
1054 '(77 93 141 181 197 277 440 441 442 443 444 457))
1056 (if (ethio-prefer-amharic-p)
1057 (aset ethio-fidel-to-sera-map 160 "a")
1058 (aset ethio-fidel-to-sera-map 160 "e"))
1059 ;; end of user's preference
1061 ;; first, decompose geminated characters
1062 (decompose-region (point-min) (point-max))
1064 ;; main conversion routine
1065 (goto-char (point-min))
1066 (while (not (eobp))
1067 (setq ch (following-char))
1069 (cond ; ethiopic, english, neutral
1071 ;; ethiopic character. must go to ethiopic mode, if not in it.
1072 ((eq (char-charset ch) 'ethiopic)
1073 (setq ch (ethio-char-to-ethiocode ch))
1074 (delete-char 1)
1075 (if (not (eq mode 'ethiopic))
1076 (progn
1077 (insert flag)
1078 (setq mode 'ethiopic)))
1080 (cond ; fidel, punc, digit
1082 ;; fidels
1083 ((or (<= ch 346) ; he - fYa
1084 (and (>= ch 384) (<= ch 444)) ; `qe - pw
1085 (and (>= ch 453) (<= ch 457))) ; wWe - wW
1086 (if (and (memq ch '(160 161 162 163 164 166 167)) ; (e - ea)
1087 (or lonec
1088 (and ethio-quote-vowel-always
1089 fidel)))
1090 (insert "'"))
1091 (insert (aref ethio-fidel-to-sera-map ch))
1092 (setq lonec (ethio-lone-consonant-p ch)
1093 fidel t
1094 digit nil))
1096 ;; punctuations or icons
1097 ((or (and (>= ch 353) (<= ch 360)) ; : - :|:
1098 (>= ch 458) ; '' - ?
1099 (and (>= ch 448) (<= ch 452))) ; \~X \~e \~E \~a \~A
1100 (insert (aref ethio-fidel-to-sera-map ch))
1101 (setq lonec nil
1102 fidel nil
1103 digit nil))
1105 ;; now CH must be an ethiopic digit
1107 ;; reduction = 0 or not preceded by Ethiopic number(s)
1108 ((or (= ethio-numeric-reduction 0)
1109 (not digit))
1110 (insert "`" (aref ethio-fidel-to-sera-map ch))
1111 (setq lonec nil
1112 fidel nil
1113 digit t))
1115 ;; reduction = 2 and following 10s, 100s, 10000s
1116 ((and (= ethio-numeric-reduction 2)
1117 (memq ch '(370 379 380)))
1118 (insert (substring (aref ethio-fidel-to-sera-map ch) 1))
1119 (setq lonec nil
1120 fidel nil
1121 digit t))
1123 ;; ordinary following digits
1125 (insert (aref ethio-fidel-to-sera-map ch))
1126 (setq lonec nil
1127 fidel nil
1128 digit t))))
1130 ;; english character. must go to english mode, if not in it.
1131 ((or (and (>= ch ?a) (<= ch ?z))
1132 (and (>= ch ?A) (<= ch ?Z)))
1133 (if (not (eq mode 'english))
1134 (insert "\\~eng "))
1135 (forward-char 1)
1136 (setq mode 'english
1137 lonec nil
1138 fidel nil
1139 digit nil))
1141 ;; ch can appear both in ethiopic section and in english section.
1144 ;; we must decide the mode, if not decided yet
1145 (if (null mode)
1146 (progn
1147 (setq mode
1148 (if secondary
1149 ethio-secondary-language
1150 ethio-primary-language))
1151 (if (eq mode 'english)
1152 (insert "\\~eng ")
1153 (insert flag)
1154 (setq mode 'ethiopic)))) ; tigrigna & amharic --> ethiopic
1156 (cond ; \ , eng-mode , punc , w3 , other
1158 ;; backslash is always quoted
1159 ((= ch ?\\ )
1160 (insert "\\")
1161 (forward-char 1))
1163 ;; nothing to do if in english mode
1164 ((eq mode 'english)
1165 (forward-char 1))
1167 ;; now we must be in ethiopic mode and seeing a non-"\"
1169 ;; ascii punctuations in ethiopic mode
1170 ((looking-at "[,.;:'`?]+")
1171 (insert "\\")
1172 (goto-char (1+ (match-end 0)))) ; because we inserted one byte (\)
1174 ;; skip from "<" to ">" (or from "&" to ";") if called from w3
1175 ((and (boundp 'sera-being-called-by-w3)
1176 sera-being-called-by-w3
1177 (or (= ch ?<) (= ch ?&)))
1178 (search-forward (if (= ch ?<) ">" ";")
1179 nil 0))
1181 ;; neutral character. no need to quote. just skip it.
1183 (forward-char 1)))
1185 (setq lonec nil
1186 fidel nil
1187 digit nil)))
1188 ;; end of main conversion routine
1191 (defun ethio-lone-consonant-p (ethiocode)
1192 "If ETHIOCODE is an Ethiopic lone consonant, return t."
1193 (or (and (< ethiocode 344) (= (% ethiocode 8) 5))
1195 ;; `q `k X `g mW bW GW fW pW wW
1196 (memq ethiocode '(389 405 421 437 440 441 442 443 444 457))))
1198 ;;;###autoload
1199 (defun ethio-fidel-to-sera-mail-or-marker (&optional arg)
1200 "Execute ethio-fidel-to-sera-mail or ethio-fidel-to-sera-marker depending on the current major mode.
1201 If in rmail-mode or in mail-mode, execute the former; otherwise latter."
1203 (interactive "P")
1204 (if (or (eq major-mode 'rmail-mode)
1205 (eq major-mode 'mail-mode))
1206 (ethio-fidel-to-sera-mail)
1207 (ethio-fidel-to-sera-marker arg)))
1209 ;;;###autoload
1210 (defun ethio-fidel-to-sera-mail nil
1211 "Convert FIDEL to SERA to read/write mail and news.
1213 If the body contains at least one Ethiopic character,
1214 1) insert the string \"<sera>\" at the beginning of the body,
1215 2) insert \"</sera>\" at the end of the body, and
1216 3) convert the body into SERA.
1218 The very same procedure applies to the subject field, too."
1220 (interactive)
1221 (let ((buffer-read-only nil)
1222 border)
1223 (save-excursion
1225 ;; follow RFC822 rules instead of looking for a fixed separator
1226 (rfc822-goto-eoh)
1227 (forward-line 1)
1228 (setq border (point))
1230 ;; process body first not to change the border
1231 ;; note that the point is already at the border
1232 (if (re-search-forward "\\ce" nil t)
1233 (progn
1234 (ethio-fidel-to-sera-region border (point-max))
1235 (goto-char border)
1236 (insert "<sera>")
1237 (goto-char (point-max))
1238 (insert "</sera>")))
1240 ;; process subject
1241 (goto-char (point-min))
1242 (if (re-search-forward "^Subject: " border t)
1243 (let ((beg (point))
1244 (end (line-end-position)))
1245 (if (re-search-forward "\\ce" end t)
1246 (progn
1247 (ethio-fidel-to-sera-region beg end)
1248 (goto-char beg)
1249 (insert "<sera>")
1250 (end-of-line)
1251 (insert "</sera>")))))
1253 ;; adjust the rmail marker
1254 (if (eq major-mode 'rmail-mode)
1255 (set-marker
1256 (aref rmail-message-vector (1+ rmail-current-message))
1257 (point-max))))))
1259 ;;;###autoload
1260 (defun ethio-fidel-to-sera-marker (&optional force)
1261 "Convert the regions surrounded by \"<sera>\" and \"</sera>\" from FIDEL to SERA.
1262 The markers \"<sera>\" and \"</sera>\" themselves are not deleted."
1264 (interactive "P")
1265 (if (and buffer-read-only
1266 (not force)
1267 (not (y-or-n-p "Buffer is read-only. Force to convert? ")))
1268 (error ""))
1269 (save-excursion
1270 (goto-char (point-min))
1271 (while (re-search-forward "<sera>" nil t)
1272 (ethio-fidel-to-sera-region
1273 (point)
1274 (if (re-search-forward "</sera>" nil t)
1275 (match-beginning 0)
1276 (point-max))
1278 'force))))
1281 ;; vowel modification
1284 ;;;###autoload
1285 (defun ethio-modify-vowel nil
1286 "Modify the vowel of the FIDEL that is under the cursor."
1287 (interactive)
1288 (let ((ch (following-char))
1289 (composite nil) ; geminated or not
1290 newch base vowel modulo)
1292 (cond
1293 ;; in case of gemination
1294 ((eq (char-charset ch) 'composition)
1295 (setq ch (string-to-char (decompose-composite-char ch))
1296 composite t))
1297 ;; neither gemination nor fidel
1298 ((not (eq (char-charset ch) 'ethiopic))
1299 (error "Not a valid character.")))
1301 ;; set frequently referred character features
1302 (setq ch (ethio-char-to-ethiocode ch)
1303 base (* (/ ch 8) 8)
1304 modulo (% ch 8))
1306 (if (or (and (>= ch 344) (<= ch 380)) ;; mYa - `10000
1307 (and (>= ch 448) (<= ch 452)) ;; \~X - \~A
1308 (>= ch 458)) ;; private punctuations
1309 (error "Not a valid character."))
1311 (setq
1312 newch
1313 (cond
1315 ;; first standalone vowels
1316 ((= base 160)
1317 (if (ethio-prefer-amharic-p)
1318 (message "Modify vowel to: [auiAEIoW\"] ")
1319 (message "Modify vowel to: [euiAEIoW\"] "))
1320 (setq vowel (read-char))
1321 (cond
1322 ((= vowel ?e) 160)
1323 ((= vowel ?u) 161)
1324 ((= vowel ?i) 162)
1325 ((= vowel ?A) 163)
1326 ((= vowel ?E) 164)
1327 ((= vowel ?I) 165)
1328 ((= vowel ?o) 166)
1329 ((= vowel ?W) 167)
1330 ((= vowel ?a) (if (ethio-prefer-amharic-p) 160 163))
1331 ((= vowel ?\") (setq composite t) ch)
1332 (t nil)))
1334 ;; second standalone vowels
1335 ((= base 208)
1336 (message "Modify vowel to: [euiaEIo\"] ")
1337 (setq vowel (read-char))
1338 (cond
1339 ((= vowel ?e) 208)
1340 ((= vowel ?u) 209)
1341 ((= vowel ?i) 210)
1342 ((= vowel ?a) 211)
1343 ((= vowel ?E) 212)
1344 ((= vowel ?I) 213)
1345 ((= vowel ?o) 214)
1346 ((= vowel ?\") (setq composite t) ch)
1347 (t nil)))
1349 ;; 12-form consonants, *W* form
1350 ((memq base '(72 88 136 176 192 272)) ; qW QW hW kW KW gW
1351 (message "Modify vowel to: [euiaE'\"] ")
1352 (setq vowel (read-char))
1353 (cond
1354 ((= vowel ?e) base)
1355 ((= vowel ?u) (+ base 5))
1356 ((= vowel ?i) (+ base 2))
1357 ((= vowel ?a) (+ base 3))
1358 ((= vowel ?E) (+ base 4))
1359 ((= vowel ?') (+ base 5))
1360 ((= vowel ?\") (setq composite t) ch)
1361 (t nil)))
1363 ;; extended 12-form consonants, mWa bWa GWa fWa pWa
1364 ((= ch 31) ; mWa
1365 (message "Modify vowel to: [euiaE'\"] ")
1366 (setq vowel (read-char))
1367 (cond
1368 ((= vowel ?e) 392)
1369 ((= vowel ?u) 440)
1370 ((= vowel ?i) 408)
1371 ((= vowel ?a) ch)
1372 ((= vowel ?E) 424)
1373 ((= vowel ?') 440)
1374 ((= vowel ?\") (setq composite t) ch)
1375 (t nil)))
1376 ((= ch 103) ; bWa
1377 (message "Modify vowel to: [euiaE'\"] ")
1378 (setq vowel (read-char))
1379 (cond
1380 ((= vowel ?e) 393)
1381 ((= vowel ?u) 441)
1382 ((= vowel ?i) 409)
1383 ((= vowel ?a) ch)
1384 ((= vowel ?E) 425)
1385 ((= vowel ?') 441)
1386 ((= vowel ?\") (setq composite t) ch)
1387 (t nil)))
1388 ((= ch 287) ; GWa
1389 (message "Modify vowel to: [euiaE'\"] ")
1390 (setq vowel (read-char))
1391 (cond
1392 ((= vowel ?e) 394)
1393 ((= vowel ?u) 442)
1394 ((= vowel ?i) 410)
1395 ((= vowel ?a) ch)
1396 ((= vowel ?E) 426)
1397 ((= vowel ?') 442)
1398 ((= vowel ?\") (setq composite t) ch)
1399 (t nil)))
1400 ((= ch 335) ; fWa
1401 (message "Modify vowel to: [euiaE'\"] ")
1402 (setq vowel (read-char))
1403 (cond
1404 ((= vowel ?e) 395)
1405 ((= vowel ?u) 443)
1406 ((= vowel ?i) 411)
1407 ((= vowel ?a) ch)
1408 ((= vowel ?E) 427)
1409 ((= vowel ?') 443)
1410 ((= vowel ?\") (setq composite t) ch)
1411 (t nil)))
1412 ((= ch 343) ; pWa
1413 (message "Modify vowel to: [euiaE'\"] ")
1414 (setq vowel (read-char))
1415 (cond
1416 ((= vowel ?e) 396)
1417 ((= vowel ?u) 444)
1418 ((= vowel ?i) 412)
1419 ((= vowel ?a) ch)
1420 ((= vowel ?E) 428)
1421 ((= vowel ?') 444)
1422 ((= vowel ?\") (setq composite t) ch)
1423 (t nil)))
1425 ;; extended 12-form consonatns, mW* bW* GW* fW* pW*
1426 ((memq base '(392 408 424 440)) ; *We *Wi *WE *W
1427 (message "Modify vowel to: [eiEau'\"] ")
1428 (setq vowel (read-char))
1429 (cond
1430 ((= vowel ?e) (+ 392 modulo))
1431 ((= vowel ?i) (+ 408 modulo))
1432 ((= vowel ?E) (+ 424 modulo))
1433 ((= vowel ?a) (cond
1434 ((= modulo 0) 31) ; mWa
1435 ((= modulo 1) 103) ; bWa
1436 ((= modulo 2) 287) ; GWa
1437 ((= modulo 3) 335) ; fWa
1438 ((= modulo 4) 343) ; pWa
1439 (t nil))) ; never reach here
1440 ((= vowel ?') (+ 440 modulo))
1441 ((= vowel ?u) (+ 440 modulo))
1442 ((= vowel ?\") (setq composite t) ch)
1443 (t nil)))
1445 ((and (>= ch 453) (<= ch 457)) ; wWe wWi wWa wWE wW
1446 (message "Modify vowel to: [eiaE'u\"] ")
1447 (setq vowel (read-char))
1448 (cond
1449 ((= vowel ?e) 453)
1450 ((= vowel ?i) 454)
1451 ((= vowel ?a) 455)
1452 ((= vowel ?E) 456)
1453 ((= vowel ?') 457)
1454 ((= vowel ?u) 457)
1455 ((= vowel ?\") (setq composite t) ch)
1456 (t nil)))
1458 ;; 7-form consonants, or
1459 ;; first 7 of 8-form consonants
1460 ((<= modulo 6)
1461 (message "Modify vowel to: [euiaE'o\"] ")
1462 (setq vowel (read-char))
1463 (cond
1464 ((= vowel ?e) base)
1465 ((= vowel ?u) (+ base 1))
1466 ((= vowel ?i) (+ base 2))
1467 ((= vowel ?a) (+ base 3))
1468 ((= vowel ?E) (+ base 4))
1469 ((= vowel ?') (+ base 5))
1470 ((= vowel ?o) (+ base 6))
1471 ((= vowel ?\") (setq composite t) ch)
1472 (t nil)))
1474 ;; otherwise
1476 nil)))
1478 (cond
1480 ;; could not get new character
1481 ((null newch)
1482 (error "Invalid vowel"))
1484 ;; vowel changed on a composite Fidel
1485 (composite
1486 (delete-char 1)
1487 (insert
1488 (compose-string
1489 (concat (char-to-string (ethio-ethiocode-to-char newch)) "\e$(3%s\e(B"))))
1491 ;; simple vowel modification
1493 (delete-char 1)
1494 (insert (ethio-ethiocode-to-char newch))))))
1496 (defun ethio-ethiocode-to-char (ethiocode)
1497 (make-char
1498 'ethiopic
1499 (+ (/ ethiocode 94) 33)
1500 (+ (mod ethiocode 94) 33)))
1502 (defun ethio-char-to-ethiocode (ch)
1503 (and (eq (char-charset ch) 'ethiopic)
1504 (let ((char-components (split-char ch)))
1505 (+ (* (- (nth 1 char-components) 33) 94)
1506 (- (nth 2 char-components) 33)))))
1509 ;; space replacement
1512 ;;;###autoload
1513 (defun ethio-replace-space (ch begin end)
1514 "Replace ASCII spaces with Ethiopic word separators in the region.
1516 In the specified region, replace word separators surrounded by two
1517 Ethiopic characters, depending on the first parameter CH, which should
1518 be 1, 2, or 3.
1520 If CH = 1, word separator will be replaced with an ASCII space.
1521 If CH = 2, with two ASCII spaces.
1522 If CH = 3, with the Ethiopic colon-like word separator.
1524 The second and third parameters BEGIN and END specify the region."
1526 (interactive "*cReplace spaces to: 1 (sg col), 2 (dbl col), 3 (Ethiopic)\nr")
1527 (if (not (memq ch '(?1 ?2 ?3)))
1528 (error ""))
1529 (save-excursion
1530 (save-restriction
1531 (narrow-to-region begin end)
1533 (cond
1534 ((= ch ?1)
1535 ;; an Ethiopic word separator --> an ASCII space
1536 (goto-char (point-min))
1537 (while (search-forward "\e$(3$h\e(B" nil t)
1538 (replace-match " " nil t))
1540 ;; two ASCII spaces between Ethiopic characters --> an ASCII space
1541 (goto-char (point-min))
1542 (while (re-search-forward "\\(\\ce\\) \\(\\ce\\)" nil t)
1543 (replace-match "\\1 \\2")
1544 (goto-char (match-beginning 2))))
1546 ((= ch ?2)
1547 ;; An Ethiopic word separator --> two ASCII spaces
1548 (goto-char (point-min))
1549 (while (search-forward "\e$(3$h\e(B" nil t)
1550 (replace-match " "))
1552 ;; An ASCII space between Ethiopic characters --> two ASCII spaces
1553 (goto-char (point-min))
1554 (while (re-search-forward "\\(\\ce\\) \\(\\ce\\)" nil t)
1555 (replace-match "\\1 \\2")
1556 (goto-char (match-beginning 2))))
1559 ;; One or two ASCII spaces between Ethiopic characters
1560 ;; --> An Ethiopic word separator
1561 (goto-char (point-min))
1562 (while (re-search-forward "\\(\\ce\\) ?\\(\\ce\\)" nil t)
1563 (replace-match "\\1\e$(3$h\e(B\\2")
1564 (goto-char (match-beginning 2)))
1566 ;; Three or more ASCII spaces between Ethiopic characters
1567 ;; --> An Ethiopic word separator + (N - 2) ASCII spaces
1568 (goto-char (point-min))
1569 (while (re-search-forward "\\(\\ce\\) \\( *\\ce\\)" nil t)
1570 (replace-match "\\1\e$(3$h\e(B\\2")
1571 (goto-char (match-beginning 2))))))))
1574 ;; special icons
1577 ;;;###autoload
1578 (defun ethio-input-special-character (arg)
1579 "Allow the user to input special characters."
1580 (interactive "*cInput number: 1.\e$(3%j\e(B 2.\e$(3%k\e(B 3.\e$(3%l\e(B 4.\e$(3%m\e(B 5.\e$(3%i\e(B")
1581 (cond
1582 ((= arg ?1)
1583 (insert "\e$(3%j\e(B"))
1584 ((= arg ?2)
1585 (insert "\e$(3%k\e(B"))
1586 ((= arg ?3)
1587 (insert "\e$(3%l\e(B"))
1588 ((= arg ?4)
1589 (insert "\e$(3%m\e(B"))
1590 ((= arg ?5)
1591 (insert "\e$(3%i\e(B"))
1593 (error ""))))
1596 ;; TeX support
1599 (defconst ethio-fidel-to-tex-map
1600 [ "heG" "huG" "hiG" "haG" "hEG" "hG" "hoG" "" ;; 0 - 7
1601 "leG" "luG" "liG" "laG" "lEG" "lG" "loG" "lWaG" ;; 8
1602 "HeG" "HuG" "HiG" "HaG" "HEG" "HG" "HoG" "HWaG" ;; 16
1603 "meG" "muG" "miG" "maG" "mEG" "mG" "moG" "mWaG" ;; 24
1604 "sseG" "ssuG" "ssiG" "ssaG" "ssEG" "ssG" "ssoG" "ssWaG" ;; 32
1605 "reG" "ruG" "riG" "raG" "rEG" "rG" "roG" "rWaG" ;; 40
1606 "seG" "suG" "siG" "saG" "sEG" "sG" "soG" "sWaG" ;; 48
1607 "xeG" "xuG" "xiG" "xaG" "xEG" "xG" "xoG" "xWaG" ;; 56
1608 "qeG" "quG" "qiG" "qaG" "qEG" "qG" "qoG" "" ;; 64
1609 "qWeG" "" "qWiG" "qWaG" "qWEG" "qWG" "" "" ;; 72
1610 "QeG" "QuG" "QiG" "QaG" "QEG" "QG" "QoG" "" ;; 80
1611 "QWeG" "" "QWiG" "QWaG" "QWEG" "QWG" "" "" ;; 88
1612 "beG" "buG" "biG" "baG" "bEG" "bG" "boG" "bWaG" ;; 96
1613 "veG" "vuG" "viG" "vaG" "vEG" "vG" "voG" "vWaG" ;; 104
1614 "teG" "tuG" "tiG" "taG" "tEG" "tG" "toG" "tWaG" ;; 112
1615 "ceG" "cuG" "ciG" "caG" "cEG" "cG" "coG" "cWaG" ;; 120
1616 "hheG" "hhuG" "hhiG" "hhaG" "hhEG" "hhG" "hhoG" "" ;; 128
1617 "hWeG" "" "hWiG" "hWaG" "hWEG" "hWG" "" "" ;; 136
1618 "neG" "nuG" "niG" "naG" "nEG" "nG" "noG" "nWaG" ;; 144
1619 "NeG" "NuG" "NiG" "NaG" "NEG" "NG" "NoG" "NWaG" ;; 152
1620 "eG" "uG" "iG" "AG" "EG" "IG" "oG" "eaG" ;; 160
1621 "keG" "kuG" "kiG" "kaG" "kEG" "kG" "koG" "" ;; 168
1622 "kWeG" "" "kWiG" "kWaG" "kWEG" "kWG" "" "" ;; 176
1623 "KeG" "KuG" "KiG" "KaG" "KEG" "KG" "KoG" "" ;; 184
1624 "KWeG" "" "KWiG" "KWaG" "KWEG" "KWG" "" "" ;; 192
1625 "weG" "wuG" "wiG" "waG" "wEG" "wG" "woG" "" ;; 200
1626 "eeG" "uuG" "iiG" "aaG" "EEG" "IIG" "ooG" "" ;; 208
1627 "zeG" "zuG" "ziG" "zaG" "zEG" "zG" "zoG" "zWaG" ;; 216
1628 "ZeG" "ZuG" "ZiG" "ZaG" "ZEG" "ZG" "ZoG" "ZWaG" ;; 224
1629 "yeG" "yuG" "yiG" "yaG" "yEG" "yG" "yoG" "yWaG" ;; 232
1630 "deG" "duG" "diG" "daG" "dEG" "dG" "doG" "dWaG" ;; 240
1631 "DeG" "DuG" "DiG" "DaG" "DEG" "DG" "DoG" "DWaG" ;; 248
1632 "jeG" "juG" "jiG" "jaG" "jEG" "jG" "joG" "jWaG" ;; 256
1633 "geG" "guG" "giG" "gaG" "gEG" "gG" "goG" "" ;; 264
1634 "gWeG" "" "gWiG" "gWaG" "gWEG" "gWG" "" "" ;; 272
1635 "GeG" "GuG" "GiG" "GaG" "GEG" "GG" "GoG" "GWaG" ;; 280
1636 "TeG" "TuG" "TiG" "TaG" "TEG" "TG" "ToG" "TWaG" ;; 288
1637 "CeG" "CuG" "CiG" "CaG" "CEG" "CG" "CoG" "CWaG" ;; 296
1638 "PeG" "PuG" "PiG" "PaG" "PEG" "PG" "PoG" "PWaG" ;; 304
1639 "SeG" "SuG" "SiG" "SaG" "SEG" "SG" "SoG" "SWaG" ;; 312
1640 "SSeG" "SSuG" "SSiG" "SSaG" "SSEG" "SSG" "SSoG" "" ;; 320
1641 "feG" "fuG" "fiG" "faG" "fEG" "fG" "foG" "fWaG" ;; 328
1642 "peG" "puG" "piG" "paG" "pEG" "pG" "poG" "pWaG" ;; 336
1643 "mYaG" "rYaG" "fYaG" "" "" "" "" "" ;; 344
1644 "" "spaceG" "periodG" "commaG" ;; 352
1645 "semicolonG" "colonG" "precolonG" "oldqmarkG" ;; 356
1646 "pbreakG" "andG" "huletG" "sostG" "aratG" "amstG" "sadstG" "sabatG" ;; 360
1647 "smntG" "zeteNG" "asrG" "heyaG" "selasaG" "arbaG" "hemsaG" "slsaG" ;; 368
1648 "sebaG" "semanyaG" "zeTanaG" "metoG" "asrxiG" "" "" "" ;; 376
1649 "qqeG" "qquG" "qqiG" "qqaG" "qqEG" "qqG" "qqoG" "" ;; 384
1650 "mWeG" "bWeG" "GWeG" "fWeG" "pWeG" "" "" "" ;; 392
1651 "kkeG" "kkuG" "kkiG" "kkaG" "kkEG" "kkG" "kkoG" "" ;; 400
1652 "mWiG" "bWiG" "GWiG" "fWiG" "pWiG" "" "" "" ;; 408
1653 "XeG" "XuG" "GXiG" "XaG" "XEG" "XG" "XoG" "" ;; 416
1654 "mWEG" "bWEG" "GWEG" "fWEG" "pWEG" "" "" "" ;; 424
1655 "ggeG" "gguG" "ggiG" "ggaG" "ggEG" "ggG" "ggoG" "" ;; 432
1656 "mWG" "bWG" "GWG" "fWG" "pWG" "" "" "" ;; 440
1657 "ornamentG" "flandG" "iflandG" "africaG" ;; 448
1658 "iafricaG" "wWeG" "wWiG" "wWaG" ;; 452
1659 "wWEG" "wWG" "" "slaqG" "dotG" "lquoteG" "rquoteG" "qmarkG" ]) ;; 456
1662 ;; To make tex-to-fidel mapping.
1663 ;; The following code makes
1664 ;; (get 'ethio-tex-command-he 'ethio-fidel-char) ==> ?\e$(3!!\e(B
1665 ;; etc.
1668 (let ((i 0) str)
1669 (while (< i (length ethio-fidel-to-tex-map))
1670 (setq str (aref ethio-fidel-to-tex-map i))
1671 (if (not (string= str ""))
1672 (put
1673 (intern (concat "ethio-tex-command-" (aref ethio-fidel-to-tex-map i)))
1674 'ethio-fidel-char
1675 (ethio-ethiocode-to-char i)))
1676 (setq i (1+ i))))
1678 ;;;###autoload
1679 (defun ethio-fidel-to-tex-buffer nil
1680 "Convert each fidel characters in the current buffer into a fidel-tex command.
1681 Each command is always surrounded by braces."
1682 (interactive)
1683 (let ((buffer-read-only nil))
1685 ;; Isolated gemination marks need special treatement
1686 (goto-char (point-min))
1687 (while (search-forward "\e$(3%s\e(B" nil t)
1688 (replace-match "\\geminateG{}" t t))
1690 ;; First, decompose geminations
1691 ;; Here we assume that each composed character consists of
1692 ;; one Ethiopic character and the Ethiopic gemination mark.
1693 (decompose-region (point-min) (point-max))
1695 ;; Special treatment for geminated characters
1696 ;; The geminated character (la'') will be "\geminateG{\la}".
1697 (goto-char (point-min))
1698 (while (search-forward "\e$(3%s\e(B" nil t)
1699 (delete-backward-char 1)
1700 (backward-char 1)
1701 (insert "\\geminateG")
1702 (forward-char 1))
1704 ;; Ethiopic characters to TeX macros
1705 (goto-char (point-min))
1706 (while (re-search-forward "\\ce" nil t)
1707 (insert
1708 "{\\"
1709 (aref ethio-fidel-to-tex-map
1710 (prog1 (ethio-char-to-ethiocode (preceding-char))
1711 (backward-delete-char 1)))
1712 "}"))
1713 (goto-char (point-min))
1714 (set-buffer-modified-p nil)))
1716 ;;;###autoload
1717 (defun ethio-tex-to-fidel-buffer nil
1718 "Convert fidel-tex commands in the current buffer into fidel chars."
1719 (interactive)
1720 (let ((buffer-read-only nil)
1721 (p) (ch))
1723 ;; Special treatment for gemination
1724 ;; "\geminateG{\la}" or "\geminateG{{\la}}" will be "\la\e$(3%s\e(B"
1725 ;; "\geminateG{}" remains unchanged.
1726 (goto-char (point-min))
1727 (while (re-search-forward "\\\\geminateG{\\(\\\\[a-zA-Z]+\\)}" nil t)
1728 (replace-match "\\1\e$(3%s\e(B"))
1730 ;; TeX macros to Ethiopic characters
1731 (goto-char (point-min))
1732 (while (search-forward "\\" nil t)
1733 (setq p (point))
1734 (skip-chars-forward "a-zA-Z")
1735 (setq ch
1736 (get (intern (concat "ethio-tex-command-"
1737 (buffer-substring p (point))))
1738 'ethio-fidel-char))
1739 (if ch
1740 (progn
1741 (delete-region (1- p) (point)) ; don't forget the preceding "\"
1742 (if (and (= (preceding-char) ?{)
1743 (= (following-char) ?}))
1744 (progn
1745 (backward-delete-char 1)
1746 (delete-char 1)))
1747 (insert ch))))
1749 ;; compose geminated characters
1750 (goto-char (point-min))
1751 (while (re-search-forward "\\ce\e$(3%s\e(B" nil 0)
1752 (compose-region
1753 (save-excursion (backward-char 2) (point))
1754 (point)))
1756 ;; Now it's time to convert isolated gemination marks.
1757 (goto-char (point-min))
1758 (while (search-forward "\\geminateG{}" nil t)
1759 (replace-match "\e$(3%s\e(B"))
1761 (goto-char (point-min))
1762 (set-buffer-modified-p nil)))
1765 ;; Java support
1768 ;;;###autoload
1769 (defun ethio-fidel-to-java-buffer nil
1770 "Convert Ethiopic characters into the Java escape sequences.
1772 Each escape sequence is of the form \uXXXX, where XXXX is the
1773 character's codepoint (in hex) in Unicode.
1775 If `ethio-java-save-lowercase' is non-nil, use [0-9a-f].
1776 Otherwise, [0-9A-F]."
1777 (let ((ucode))
1779 ;; first, decompose geminations
1780 (decompose-region (point-min) (point-max))
1782 (goto-char (point-min))
1783 (while (re-search-forward "\\ce" nil t)
1784 (setq ucode (+ ?\x1200 (ethio-char-to-ethiocode (preceding-char))))
1785 (if (> ucode ?\x13bc)
1786 (setq ucode (+ ucode 59952)))
1787 (delete-backward-char 1)
1788 (if ethio-java-save-lowercase
1789 (insert (format "\\u%4x" ucode))
1790 (insert (upcase (format "\\u%4x" ucode)))))))
1792 ;;;###autoload
1793 (defun ethio-java-to-fidel-buffer nil
1794 "Convert the Java escape sequences into corresponding Ethiopic characters."
1795 (let ((ucode))
1796 (goto-char (point-min))
1797 (while (re-search-forward "\\\\u\\([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\\)" nil t)
1798 (setq ucode
1799 (read
1800 (concat
1801 "?\\x"
1802 (buffer-substring (match-beginning 1) (match-end 1)))))
1803 (cond
1804 ((and (>= ucode ?\x1200) (<= ucode ?\x13bc))
1805 (replace-match "")
1806 (insert (ethio-ethiocode-to-char (- ucode ?\x1200))))
1807 ((and (>= ucode ?\xfdf1) (<= ucode ?\xfdff))
1808 (replace-match "")
1809 (insert (ethio-ethiocode-to-char (- ucode 64560))))
1811 nil)))
1813 ;; gemination
1814 (goto-char (point-min))
1815 (while (re-search-forward "\\ce\e$(3%s\e(B" nil 0)
1816 (compose-region
1817 (save-excursion (backward-char 2) (point))
1818 (point)))
1822 ;; file I/O hooks
1825 ;;;###autoload
1826 (defun ethio-find-file nil
1827 "Transcribe file content into Ethiopic dependig on filename suffix."
1828 (cond
1830 ((string-match "\\.sera$" (buffer-file-name))
1831 (save-excursion
1832 (ethio-sera-to-fidel-buffer nil 'force)
1833 (set-buffer-modified-p nil)))
1835 ((string-match "\\.html$" (buffer-file-name))
1836 (let ((sera-being-called-by-w3 t))
1837 (save-excursion
1838 (ethio-sera-to-fidel-marker 'force)
1839 (goto-char (point-min))
1840 (while (re-search-forward "&[lr]aquote;" nil t)
1841 (if (= (char-after (1+ (match-beginning 0))) ?l)
1842 (replace-match "\e$(3%v\e(B")
1843 (replace-match "\e$(3%w\e(B")))
1844 (set-buffer-modified-p nil))))
1846 ((string-match "\\.tex$" (buffer-file-name))
1847 (save-excursion
1848 (ethio-tex-to-fidel-buffer)
1849 (set-buffer-modified-p nil)))
1851 ((string-match "\\.java$" (buffer-file-name))
1852 (save-excursion
1853 (ethio-java-to-fidel-buffer)
1854 (set-buffer-modified-p nil)))
1857 nil)))
1859 ;;;###autoload
1860 (defun ethio-write-file nil
1861 "Transcribe Ethiopic characters in ASCII depending on the file extension."
1862 (cond
1864 ((string-match "\\.sera$" (buffer-file-name))
1865 (save-excursion
1866 (ethio-fidel-to-sera-buffer nil 'force)
1867 (goto-char (point-min))
1868 (ethio-record-user-preference)
1869 (set-buffer-modified-p nil)))
1871 ((string-match "\\.html$" (buffer-file-name))
1872 (save-excursion
1873 (let ((sera-being-called-by-w3 t)
1874 (lq (aref ethio-fidel-to-sera-map 461))
1875 (rq (aref ethio-fidel-to-sera-map 462)))
1876 (aset ethio-fidel-to-sera-map 461 "&laquote;")
1877 (aset ethio-fidel-to-sera-map 462 "&raquote;")
1878 (ethio-fidel-to-sera-marker 'force)
1879 (goto-char (point-min))
1880 (if (search-forward "<sera>" nil t)
1881 (ethio-record-user-preference))
1882 (aset ethio-fidel-to-sera-map 461 lq)
1883 (aset ethio-fidel-to-sera-map 462 rq)
1884 (set-buffer-modified-p nil))))
1886 ((string-match "\\.tex$" (buffer-file-name))
1887 (save-excursion
1888 (ethio-fidel-to-tex-buffer)
1889 (set-buffer-modified-p nil)))
1891 ((string-match "\\.java$" (buffer-file-name))
1892 (save-excursion
1893 (ethio-fidel-to-java-buffer)
1894 (set-buffer-modified-p nil)))
1897 nil)))
1899 (defun ethio-record-user-preference nil
1900 (if (looking-at "\\\\~\\(tir?\\|amh?\\) ")
1901 (goto-char (match-end 0))
1902 (insert (if (ethio-prefer-amharic-p) "\\~amh " "\\~tir ")))
1903 (insert (if ethio-use-colon-for-colon "\\~-: " "\\~`: ")
1904 (if ethio-use-three-dot-question "\\~`| " "\\~`? ")))
1907 ;; Ethiopic word separator vs. ASCII space
1910 (defvar ethio-prefer-ascii-space t)
1911 (make-variable-buffer-local 'ethio-prefer-ascii-space)
1913 (defun ethio-toggle-space nil
1914 "Toggle ASCII space and Ethiopic separator for keyboard input."
1915 (interactive)
1916 (setq ethio-prefer-ascii-space
1917 (not ethio-prefer-ascii-space))
1918 (if (equal current-input-method "ethiopic")
1919 (setq current-input-method-title (quail-title)))
1920 (force-mode-line-update))
1922 (defun ethio-insert-space (arg)
1923 "Insert ASCII spaces or Ethiopic word separators depending on context.
1925 If the current word separator (indicated in mode-line) is the ASCII space,
1926 insert an ASCII space. With ARG, insert that many ASCII spaces.
1928 If the current word separator is the colon-like Ethiopic word
1929 separator and the point is preceded by `an Ethiopic punctuation mark
1930 followed by zero or more ASCII spaces', then insert also an ASCII
1931 space. With ARG, insert that many ASCII spaces.
1933 Otherwise, insert a colon-like Ethiopic word separator. With ARG, insert that
1934 many Ethiopic word separators."
1936 (interactive "*p")
1937 (cond
1938 (ethio-prefer-ascii-space
1939 (insert-char 32 arg))
1940 ((save-excursion
1941 (skip-chars-backward " ")
1942 (memq (preceding-char)
1943 '(?\e$(3$h\e(B ?\e$(3$i\e(B ?\e$(3$j\e(B ?\e$(3$k\e(B ?\e$(3$l\e(B ?\e$(3$m\e(B ?\e$(3$n\e(B ?\e$(3$o\e(B ?\e$(3%t\e(B ?\e$(3%u\e(B ?\e$(3%v\e(B ?\e$(3%w\e(B ?\e$(3%x\e(B)))
1944 (insert-char 32 arg))
1946 (insert-char ?\e$(3$h\e(B arg))))
1948 (defun ethio-insert-ethio-space (arg)
1949 "Insert the Ethiopic word delimiter (the colon-like character).
1950 With ARG, insert that many delimiters."
1951 (interactive "*p")
1952 (insert-char ?\e$(3$h\e(B arg))
1955 ;; Ethiopic punctuation vs. ASCII punctuation
1958 (defvar ethio-prefer-ascii-punctuation nil)
1959 (make-variable-buffer-local 'ethio-prefer-ascii-punctuation)
1961 (defun ethio-toggle-punctuation nil
1962 "Toggle Ethiopic punctuations and ASCII punctuations for keyboard input."
1963 (interactive)
1964 (setq ethio-prefer-ascii-punctuation
1965 (not ethio-prefer-ascii-punctuation))
1966 (let* ((keys '("." ".." "..." "," ",," ";" ";;" ":" "::" ":::" "*" "**"))
1967 (puncs
1968 (if ethio-prefer-ascii-punctuation
1969 '(?. [".."] ["..."] ?, [",,"] ?\; [";;"] ?: ["::"] [":::"] ?* ["**"])
1970 '(?\e$(3$i\e(B ?\e$(3%u\e(B ?. ?\e$(3$j\e(B ?, ?\e$(3$k\e(B ?\; ?\e$(3$h\e(B ?\e$(3$i\e(B ?: ?* ?\e$(3$o\e(B))))
1971 (while keys
1972 (quail-defrule (car keys) (car puncs) "ethiopic")
1973 (setq keys (cdr keys)
1974 puncs (cdr puncs)))
1975 (if (equal current-input-method "ethiopic")
1976 (setq current-input-method-title (quail-title)))
1977 (force-mode-line-update)))
1980 ;; Gemination
1983 (defun ethio-gemination nil
1984 "Compose the character before the point with the Ethiopic gemination mark.
1985 If the characater is already composed, decompose it and remove the gemination
1986 mark."
1987 (interactive "*")
1988 (cond
1989 ((eq (char-charset (preceding-char)) 'ethiopic)
1990 (insert "\e$(3%s\e(B")
1991 (compose-region
1992 (save-excursion (backward-char 2) (point))
1993 (point))
1994 (forward-char 1))
1995 ((eq (char-charset (preceding-char)) 'leading-code-composition)
1996 (decompose-region
1997 (save-excursion (backward-char 1) (point))
1998 (point))
1999 (delete-backward-char 1))
2001 (error ""))))
2004 (provide 'ethio-util)
2006 ;;; ethio-util.el ends here