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