Update Appointments section.
[emacs.git] / lisp / language / ethio-util.el
blob90eed288d6c74e53086dc6aedccc37b031071710
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 ;;;###autoload
421 (defun ethio-sera-to-fidel-region (beg end &optional secondary force)
422 "Convert the characters in region from SERA to FIDEL.
423 The variable `ethio-primary-language' specifies the primary language
424 and `ethio-secondary-language' specifies the secondary.
426 If the 3rd parameter SECONDARY is given and non-nil, assume the region
427 begins begins with the secondary language; otherwise with the primary
428 language.
430 If the 4th parameter FORCE is given and non-nil, perform conversion
431 even if the buffer is read-only.
433 See also the descriptions of the variables
434 `ethio-use-colon-for-colon' and
435 `ethio-use-three-dot-question'."
437 (interactive "r\nP")
438 (save-restriction
439 (narrow-to-region beg end)
440 (ethio-sera-to-fidel-buffer secondary force)))
442 ;;;###autoload
443 (defun ethio-sera-to-fidel-buffer (&optional secondary force)
444 "Convert the current buffer from SERA to FIDEL.
446 The variable `ethio-primary-language' specifies the primary
447 language and `ethio-secondary-language' specifies the secondary.
449 If the 1st optional parameter SECONDARY is non-nil, assume the buffer
450 begins with the secondary language; otherwise with the primary
451 language.
453 If the 2nd optional parametr FORCE is non-nil, perform conversion even if the
454 buffer is read-only.
456 See also the descriptions of the variables
457 `ethio-use-colon-for-colon' and
458 `ethio-use-three-dot-question'."
460 (interactive "P")
462 (if (and buffer-read-only
463 (not force)
464 (not (y-or-n-p "Buffer is read-only. Force to convert? ")))
465 (error ""))
467 (let ((ethio-primary-language ethio-primary-language)
468 (ethio-secondary-language ethio-secondary-language)
469 (ethio-use-colon-for-colon ethio-use-colon-for-colon)
470 (ethio-use-three-dot-question ethio-use-three-dot-question)
471 ;; The above four variables may be changed temporary
472 ;; by tilde escapes during conversion. So we bind them to other
473 ;; variables but of the same names.
474 (buffer-read-only nil)
475 (case-fold-search nil)
476 current-language
477 next-language)
479 (setq current-language
480 (if secondary
481 ethio-secondary-language
482 ethio-primary-language))
484 (goto-char (point-min))
486 (while (not (eobp))
487 (setq next-language
488 (cond
489 ((eq current-language 'english)
490 (ethio-sera-to-fidel-english))
491 ((eq current-language 'amharic)
492 (ethio-sera-to-fidel-ethio 'amharic))
493 ((eq current-language 'tigrigna)
494 (ethio-sera-to-fidel-ethio 'tigrigna))
495 (t ; we don't know what to do
496 (ethio-sera-to-fidel-english))))
498 (setq current-language
499 (cond
501 ;; when language tag is explicitly specified
502 ((not (eq next-language 'toggle))
503 next-language)
505 ;; found a toggle in a primary language section
506 ((eq current-language ethio-primary-language)
507 ethio-secondary-language)
509 ;; found a toggle in a secondary, third, fourth, ...
510 ;; language section
512 ethio-primary-language))))
514 ;; If ethio-implicit-period-conversion is non-nil, the
515 ;; Ethiopic dot "\e$(3%u\e(B" at the end of an Ethiopic sentence is
516 ;; replaced with the Ethiopic full stop "\e$(3$i\e(B".
517 (if ethio-implicit-period-conversion
518 (progn
519 (goto-char (point-min))
520 (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]\\)"
521 nil t)
522 (replace-match "\\1\e$(3$i\e(B\\2"))
523 (goto-char (point-min))
524 (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)
525 (replace-match "\\1\e$(3$i\e(B"))))
527 ;; gemination
528 (goto-char (point-min))
529 (while (re-search-forward "\\ce\e$(3%s\e(B" nil 0)
530 (compose-region
531 (save-excursion (backward-char 2) (point))
532 (point)))
535 (defun ethio-sera-to-fidel-english nil
536 "Handle English section in SERA to FIDEL conversion.
537 Conversion stops when a language switch is found. Then delete that
538 switch and return the name of the new language as a symbol."
539 (let ((new-language nil))
541 (while (and (not (eobp)) (null new-language))
542 (cond
544 ;; if no more "\", nothing to do.
545 ((not (search-forward "\\" nil 0)))
547 ;; hereafter point is put after a "\".
548 ;; first delete that "\", then check the following chars
550 ;; "\\" : leave the second "\"
551 ((progn
552 (delete-backward-char 1)
553 (= (following-char) ?\\ ))
554 (forward-char 1))
556 ;; "\ " : delete the following " "
557 ((= (following-char) 32)
558 (delete-char 1)
559 (setq new-language 'toggle))
561 ;; a language flag
562 ((setq new-language (ethio-process-language-flag)))
564 ;; just a "\" : not special sequence.
566 (setq new-language 'toggle))))
568 new-language))
570 (defun ethio-sera-to-fidel-ethio (lang)
571 "Handle Ethiopic section in SERA to FIDEL conversion.
572 Conversion stops when a language switch is found. Then delete that
573 switch and return the name of the new language as a symbol.
575 The parameter LANG (symbol, either `amharic' or `tigrigna') affects
576 the conversion of \"a\"."
578 (let ((new-language nil)
579 (verbatim nil)
580 start table table2 ch)
582 (setcar (aref ethio-sera-to-fidel-table ?a)
583 (if (eq lang 'tigrigna) "\e$(3"f\e(B" "\e$(3"c\e(B"))
585 (while (and (not (eobp)) (null new-language))
586 (setq ch (following-char))
587 (cond
589 ;; skip from "<" to ">" (or from "&" to ";") if in w3-mode
590 ((and (boundp 'sera-being-called-by-w3)
591 sera-being-called-by-w3
592 (or (= ch ?<) (= ch ?&)))
593 (search-forward (if (= ch ?<) ">" ";")
594 nil 0))
596 ;; leave non-ASCII characters as they are
597 ((>= ch 128)
598 (forward-char 1))
600 ;; ethiopic digits
601 ((looking-at "`[1-9][0-9]*")
602 (delete-char 1)
603 (ethio-convert-digit))
605 ;; if not seeing a "\", do sera to fidel conversion
606 ((/= ch ?\\ )
607 (setq start (point))
608 (forward-char 1)
609 (setq table (aref ethio-sera-to-fidel-table ch))
610 (while (setq table2 (cdr (assoc (following-char) table)))
611 (setq table table2)
612 (forward-char 1))
613 (if (setq ch (car table))
614 (progn
615 (delete-region start (point))
616 (if (stringp ch)
617 (insert ch)
618 (insert (eval ch))))))
620 ;; if control reaches here, we must be looking at a "\"
622 ;; verbatim mode
623 (verbatim
624 (if (looking-at "\\\\~! ?")
626 ;; "\~!" or "\~! ". switch to non-verbatim mode
627 (progn
628 (replace-match "")
629 (setq verbatim nil))
631 ;; "\" but not "\~!" nor "\~! ". skip the current "\".
632 (forward-char 1)))
634 ;; hereafter, non-verbatim mode and looking at a "\"
635 ;; first delete that "\", then check the following chars.
637 ;; "\ " : delete the following " "
638 ((progn
639 (delete-char 1)
640 (setq ch (following-char))
641 (= ch 32))
642 (delete-char 1)
643 (setq new-language 'toggle))
645 ;; "\~!" or "\~! " : switch to verbatim mode
646 ((looking-at "~! ?")
647 (replace-match "")
648 (setq verbatim t))
650 ;; a language flag
651 ((setq new-language (ethio-process-language-flag)))
653 ;; "\~" but not "\~!" nor a language flag
654 ((= ch ?~)
655 (delete-char 1)
656 (ethio-tilde-escape))
658 ;; ASCII punctuation escape. skip
659 ((looking-at "\\(,\\|\\.\\|;\\|:\\|'\\|`\\|\?\\|\\\\\\)+")
660 (goto-char (match-end 0)))
662 ;; "\", but not special sequence
664 (setq new-language 'toggle))))
666 new-language))
668 (defun ethio-process-language-flag nil
669 "Process a language flag of the form \"~lang\" or \"~lang1~lang2\".
671 If looking at \"~lang1~lang2\", set `ethio-primary-language' and
672 `ethio-une-secondary-language' based on \"lang1\" and \"lang2\".
673 Then delete the language flag \"~lang1~lang2\" from the buffer.
674 Return value is the new primary language.
676 If looking at \"~lang\", delete that language flag \"~lang\" from the
677 buffer and return that language. In this case
678 `ethio-primary-language' and `ethio-uni-secondary-language'
679 are left unchanged.
681 If an unsupported language flag is found, just return nil without
682 changing anything."
684 (let (lang1 lang2)
685 (cond
687 ;; ~lang1~lang2
688 ((and (looking-at
689 "~\\([a-z][a-z][a-z]?\\)~\\([a-z][a-z][a-z]?\\)[ \t\n\\]")
690 (setq lang1
691 (ethio-flag-to-language
692 (buffer-substring (match-beginning 1) (match-end 1))))
693 (setq lang2
694 (ethio-flag-to-language
695 (buffer-substring (match-beginning 2) (match-end 2)))))
696 (setq ethio-primary-language lang1
697 ethio-secondary-language lang2)
698 (delete-region (point) (match-end 2))
699 (if (= (following-char) 32)
700 (delete-char 1))
701 ethio-primary-language)
703 ;; ~lang
704 ((and (looking-at "~\\([a-z][a-z][a-z]?\\)[ \t\n\\]")
705 (setq lang1
706 (ethio-flag-to-language
707 (buffer-substring (match-beginning 1) (match-end 1)))))
708 (delete-region (point) (match-end 1))
709 (if (= (following-char) 32)
710 (delete-char 1))
711 lang1)
713 ;; otherwise
715 nil))))
717 (defun ethio-tilde-escape nil
718 "Handle a SERA tilde escape in Ethiopic section and delete it.
719 Delete the escape even it is not recognised."
721 (let ((p (point)) command)
722 (skip-chars-forward "^ \t\n\\\\")
723 (setq command (buffer-substring p (point)))
724 (delete-region p (point))
725 (if (= (following-char) 32)
726 (delete-char 1))
728 (cond
730 ;; \~-:
731 ((string= command "-:")
732 (setq ethio-use-colon-for-colon t))
734 ;; \~`:
735 ((string= command "`:")
736 (setq ethio-use-colon-for-colon nil))
738 ;; \~?
739 ((string= command "?")
740 (setq ethio-use-three-dot-question nil))
742 ;; \~`|
743 ((string= command "`|")
744 (setq ethio-use-three-dot-question t))
746 ;; \~e
747 ((string= command "e")
748 (insert "\e$(3%j\e(B"))
750 ;; \~E
751 ((string= command "E")
752 (insert "\e$(3%k\e(B"))
754 ;; \~a
755 ((string= command "a")
756 (insert "\e$(3%l\e(B"))
758 ;; \~A
759 ((string= command "A")
760 (insert "\e$(3%m\e(B"))
762 ;; \~X
763 ((string= command "X")
764 (insert "\e$(3%i\e(B"))
766 ;; unsupported tilde escape
768 nil))))
770 (defun ethio-flag-to-language (flag)
771 (cond
772 ((or (string= flag "en") (string= flag "eng")) 'english)
773 ((or (string= flag "ti") (string= flag "tir")) 'tigrigna)
774 ((or (string= flag "am") (string= flag "amh")) 'amharic)
775 (t nil)))
777 (defun ethio-convert-digit nil
778 "Convert Arabic digits to Ethiopic digits."
779 (let (ch z)
780 (while (and (>= (setq ch (following-char)) ?1)
781 (<= ch ?9))
782 (delete-char 1)
784 ;; count up following zeros
785 (setq z 0)
786 (while (= (following-char) ?0)
787 (delete-char 1)
788 (setq z (1+ z)))
790 (cond
792 ;; first digit is 10, 20, ..., or 90
793 ((= (mod z 2) 1)
794 (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)))
795 (setq z (1- z)))
797 ;; first digit is 2, 3, ..., or 9
798 ((/= ch ?1)
799 (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))))
801 ;; single 1
802 ((= z 0)
803 (insert "\e$(3$p\e(B")))
805 ;; 100
806 (if (= (mod z 4) 2)
807 (insert "\e$(3%$\e(B"))
809 ;; 10000
810 (insert-char ?\e$(3%%\e(B (/ z 4)))))
812 ;;;###autoload
813 (defun ethio-sera-to-fidel-mail-or-marker (&optional arg)
814 "Execute ethio-sera-to-fidel-mail or ethio-sera-to-fidel-marker depending on the current major mode.
815 If in rmail-mode or in mail-mode, execute the former; otherwise latter."
817 (interactive "P")
818 (if (or (eq major-mode 'rmail-mode)
819 (eq major-mode 'mail-mode))
820 (ethio-sera-to-fidel-mail (prefix-numeric-value arg))
821 (ethio-sera-to-fidel-marker arg)))
823 ;;;###autoload
824 (defun ethio-sera-to-fidel-mail (&optional arg)
825 "Convert SERA to FIDEL to read/write mail and news.
827 If the buffer contains the markers \"<sera>\" and \"</sera>\",
828 convert the segments between them into FIDEL.
830 If invoked interactively and there is no marker, convert the subject field
831 and the body into FIDEL using `ethio-sera-to-fidel-region'."
833 (interactive "p")
834 (let ((buffer-read-only nil)
835 border)
836 (save-excursion
838 ;; follow RFC822 rules instead of looking for a fixed separator
839 (rfc822-goto-eoh)
840 (forward-line 1)
841 (setq border (point))
843 ;; note that the point is placed at the border
844 (if (or (re-search-forward "^<sera>$" nil t)
845 (progn
846 (goto-char (point-min))
847 (re-search-forward "^Subject: <sera>" border t)))
849 ;; there are markers
850 (progn
851 ;; we start with the body so that the border will not change
852 ;; use "^<sera>\n" instead of "^<sera>$" not to leave a blank line
853 (goto-char border)
854 (while (re-search-forward "^<sera>\n" nil t)
855 (replace-match "")
856 (ethio-sera-to-fidel-region
857 (point)
858 (progn
859 (if (re-search-forward "^</sera>\n" nil 0)
860 (replace-match ""))
861 (point))))
862 ;; now process the subject
863 (goto-char (point-min))
864 (if (re-search-forward "^Subject: <sera>" border t)
865 (ethio-sera-to-fidel-region
866 (progn (delete-backward-char 6) (point))
867 (progn
868 (if (re-search-forward "</sera>$" (line-end-position) 0)
869 (replace-match ""))
870 (point)))))
872 ;; in case there are no marks but invoked interactively
873 (if arg
874 (progn
875 (ethio-sera-to-fidel-region border (point-max))
876 (goto-char (point-min))
877 (if (re-search-forward "^Subject: " border t)
878 (ethio-sera-to-fidel-region (point) (line-end-position))))))
880 ;; adjust the rmail marker
881 (if (eq major-mode 'rmail-mode)
882 (set-marker
883 (aref rmail-message-vector (1+ rmail-current-message))
884 (point-max))))))
886 ;;;###autoload
887 (defun ethio-sera-to-fidel-marker (&optional force)
888 "Convert the regions surrounded by \"<sera>\" and \"</sera>\" from SERA to FIDEL.
889 Assume that each region begins with `ethio-primary-language'.
890 The markers \"<sera>\" and \"</sera>\" themselves are not deleted."
891 (interactive "P")
892 (if (and buffer-read-only
893 (not force)
894 (not (y-or-n-p "Buffer is read-only. Force to convert? ")))
895 (error ""))
896 (save-excursion
897 (goto-char (point-min))
898 (while (re-search-forward "<sera>" nil t)
899 (ethio-sera-to-fidel-region
900 (point)
901 (if (re-search-forward "</sera>" nil t)
902 (match-beginning 0)
903 (point-max))
905 'force))))
908 ;; FIDEL to SERA
911 (defconst ethio-fidel-to-sera-map
912 [ "he" "hu" "hi" "ha" "hE" "h" "ho" "" ;; 0 - 7
913 "le" "lu" "li" "la" "lE" "l" "lo" "lWa" ;; 8
914 "He" "Hu" "Hi" "Ha" "HE" "H" "Ho" "HWa" ;; 16
915 "me" "mu" "mi" "ma" "mE" "m" "mo" "mWa" ;; 24
916 "`se" "`su" "`si" "`sa" "`sE" "`s" "`so" "`sWa" ;; 32
917 "re" "ru" "ri" "ra" "rE" "r" "ro" "rWa" ;; 40
918 "se" "su" "si" "sa" "sE" "s" "so" "sWa" ;; 48
919 "xe" "xu" "xi" "xa" "xE" "x" "xo" "xWa" ;; 56
920 "qe" "qu" "qi" "qa" "qE" "q" "qo" "" ;; 64
921 "qWe" "" "qWi" "qWa" "qWE" "qW'" "" "" ;; 72
922 "Qe" "Qu" "Qi" "Qa" "QE" "Q" "Qo" "" ;; 80
923 "QWe" "" "QWi" "QWa" "QWE" "QW'" "" "" ;; 88
924 "be" "bu" "bi" "ba" "bE" "b" "bo" "bWa" ;; 96
925 "ve" "vu" "vi" "va" "vE" "v" "vo" "vWa" ;; 104
926 "te" "tu" "ti" "ta" "tE" "t" "to" "tWa" ;; 112
927 "ce" "cu" "ci" "ca" "cE" "c" "co" "cWa" ;; 120
928 "`he" "`hu" "`hi" "`ha" "`hE" "`h" "`ho" "" ;; 128
929 "hWe" "" "hWi" "hWa" "hWE" "hW'" "" "" ;; 136
930 "ne" "nu" "ni" "na" "nE" "n" "no" "nWa" ;; 144
931 "Ne" "Nu" "Ni" "Na" "NE" "N" "No" "NWa" ;; 152
932 "e" "u" "i" "A" "E" "I" "o" "ea" ;; 160
933 "ke" "ku" "ki" "ka" "kE" "k" "ko" "" ;; 168
934 "kWe" "" "kWi" "kWa" "kWE" "kW'" "" "" ;; 176
935 "Ke" "Ku" "Ki" "Ka" "KE" "K" "Ko" "" ;; 184
936 "KWe" "" "KWi" "KWa" "KWE" "KW'" "" "" ;; 192
937 "we" "wu" "wi" "wa" "wE" "w" "wo" "" ;; 200
938 "`e" "`u" "`i" "`a" "`E" "`I" "`o" "" ;; 208
939 "ze" "zu" "zi" "za" "zE" "z" "zo" "zWa" ;; 216
940 "Ze" "Zu" "Zi" "Za" "ZE" "Z" "Zo" "ZWa" ;; 224
941 "ye" "yu" "yi" "ya" "yE" "y" "yo" "yWa" ;; 232
942 "de" "du" "di" "da" "dE" "d" "do" "dWa" ;; 240
943 "De" "Du" "Di" "Da" "DE" "D" "Do" "DWa" ;; 248
944 "je" "ju" "ji" "ja" "jE" "j" "jo" "jWa" ;; 256
945 "ge" "gu" "gi" "ga" "gE" "g" "go" "" ;; 264
946 "gWe" "" "gWi" "gWa" "gWE" "gW'" "" "" ;; 272
947 "Ge" "Gu" "Gi" "Ga" "GE" "G" "Go" "GWa" ;; 280
948 "Te" "Tu" "Ti" "Ta" "TE" "T" "To" "TWa" ;; 288
949 "Ce" "Cu" "Ci" "Ca" "CE" "C" "Co" "CWa" ;; 296
950 "Pe" "Pu" "Pi" "Pa" "PE" "P" "Po" "PWa" ;; 304
951 "Se" "Su" "Si" "Sa" "SE" "S" "So" "SWa" ;; 312
952 "`Se" "`Su" "`Si" "`Sa" "`SE" "`S" "`So" "" ;; 320
953 "fe" "fu" "fi" "fa" "fE" "f" "fo" "fWa" ;; 328
954 "pe" "pu" "pi" "pa" "pE" "p" "po" "pWa" ;; 336
955 "mYa" "rYa" "fYa" "" "" "" "" "" ;; 344
956 " " " : " "::" "," ";" "-:" ":-" "`?" ;; 352
957 ":|:" "1" "2" "3" "4" "5" "6" "7" ;; 360
958 "8" "9" "10" "20" "30" "40" "50" "60" ;; 368
959 "70" "80" "90" "100" "10000" "" "" "" ;; 376
960 "`qe" "`qu" "`qi" "`qa" "`qE" "`q" "`qo" "" ;; 384
961 "mWe" "bWe" "GWe" "fWe" "pWe" "" "" "" ;; 392
962 "`ke" "`ku" "`ki" "`ka" "`kE" "`k" "`ko" "" ;; 400
963 "mWi" "bWi" "GWi" "fWi" "pWi" "" "" "" ;; 408
964 "Xe" "Xu" "Xi" "Xa" "XE" "X" "Xo" "" ;; 416
965 "mWE" "bWE" "GWE" "fWE" "pWE" "" "" "" ;; 424
966 "`ge" "`gu" "`gi" "`ga" "`gE" "`g" "`go" "" ;; 432
967 "mW'" "bW'" "GW'" "fW'" "pW'" "" "" "" ;; 440
968 "\\~X " "\\~e " "\\~E " "\\~a " "\\~A " "wWe" "wWi" "wWa" ;; 448
969 "wWE" "wW'" "''" "`!" "." "<<" ">>" "?" ]) ;; 456
971 (defun ethio-prefer-amharic-p nil
972 (or (eq ethio-primary-language 'amharic)
973 (and (not (eq ethio-primary-language 'tigrigna))
974 (eq ethio-secondary-language 'amharic))))
976 (defun ethio-language-to-flag (lang)
977 (cond
978 ((eq lang 'english) "eng")
979 ((eq lang 'tigrigna) "tir")
980 ((eq lang 'amharic) "amh")
981 (t "")))
983 ;;;###autoload
984 (defun ethio-fidel-to-sera-region (begin end &optional secondary force)
985 "Replace all the FIDEL characters in the region to the SERA format.
986 The variable `ethio-primary-language' specifies the primary
987 language and `ethio-secondary-language' specifies the secondary.
989 If the 3dr parameter SECONDARY is given and non-nil, try to convert
990 the region so that it begins in the secondary language; otherwise with
991 the primary language.
993 If the 4th parameter FORCE is given and non-nil, convert even if the
994 buffer is read-only.
996 See also the descriptions of the variables
997 `ethio-use-colon-for-colon', `ethio-use-three-dot-question',
998 `ethio-quote-vowel-always' and `ethio-numeric-reduction'."
1000 (interactive "r\nP")
1001 (save-restriction
1002 (narrow-to-region begin end)
1003 (ethio-fidel-to-sera-buffer secondary force)))
1005 ;;;###autoload
1006 (defun ethio-fidel-to-sera-buffer (&optional secondary force)
1007 "Replace all the FIDEL characters in the current buffer to the SERA format.
1008 The variable `ethio-primary-language' specifies the primary
1009 language and `ethio-secondary-language' specifies the secondary.
1011 If the 1st optional parameter SECONDARY is non-nil, try to convert the
1012 region so that it begins in the secondary language; otherwise with the
1013 primary language.
1015 If the 2nd optional parameter FORCE is non-nil, convert even if the
1016 buffer is read-only.
1018 See also the descriptions of the variables
1019 `ethio-use-colon-for-colon', `ethio-use-three-dot-question',
1020 `ethio-quote-vowel-always' and `ethio-numeric-reduction'."
1022 (interactive "P")
1023 (if (and buffer-read-only
1024 (not force)
1025 (not (y-or-n-p "Buffer is read-only. Force to convert? ")))
1026 (error ""))
1028 (let ((buffer-read-only nil)
1029 (case-fold-search nil)
1030 (lonec nil) ;; t means previous char was a lone consonant
1031 (fidel nil) ;; t means previous char was a FIDEL
1032 (digit nil) ;; t means previous char was an Ethiopic digit
1033 (flag (if (ethio-prefer-amharic-p) "\\~amh " "\\~tir "))
1034 mode ch)
1036 ;; user's preference in transcription
1037 (if ethio-use-colon-for-colon
1038 (progn
1039 (aset ethio-fidel-to-sera-map 353 "`:")
1040 (aset ethio-fidel-to-sera-map 357 ":"))
1041 (aset ethio-fidel-to-sera-map 353 " : ")
1042 (aset ethio-fidel-to-sera-map 357 "-:"))
1044 (if ethio-use-three-dot-question
1045 (progn
1046 (aset ethio-fidel-to-sera-map 359 "?")
1047 (aset ethio-fidel-to-sera-map 463 "`?"))
1048 (aset ethio-fidel-to-sera-map 359 "`?")
1049 (aset ethio-fidel-to-sera-map 463 "?"))
1051 (mapcar
1052 '(lambda (x)
1053 (aset (aref ethio-fidel-to-sera-map x)
1055 (if ethio-W-sixth-always ?' ?u)))
1056 '(77 93 141 181 197 277 440 441 442 443 444 457))
1058 (if (ethio-prefer-amharic-p)
1059 (aset ethio-fidel-to-sera-map 160 "a")
1060 (aset ethio-fidel-to-sera-map 160 "e"))
1061 ;; end of user's preference
1063 ;; first, decompose geminated characters
1064 (decompose-region (point-min) (point-max))
1066 ;; main conversion routine
1067 (goto-char (point-min))
1068 (while (not (eobp))
1069 (setq ch (following-char))
1071 (cond ; ethiopic, english, neutral
1073 ;; ethiopic character. must go to ethiopic mode, if not in it.
1074 ((eq (char-charset ch) 'ethiopic)
1075 (setq ch (ethio-char-to-ethiocode ch))
1076 (delete-char 1)
1077 (if (not (eq mode 'ethiopic))
1078 (progn
1079 (insert flag)
1080 (setq mode 'ethiopic)))
1082 (cond ; fidel, punc, digit
1084 ;; fidels
1085 ((or (<= ch 346) ; he - fYa
1086 (and (>= ch 384) (<= ch 444)) ; `qe - pw
1087 (and (>= ch 453) (<= ch 457))) ; wWe - wW
1088 (if (and (memq ch '(160 161 162 163 164 166 167)) ; (e - ea)
1089 (or lonec
1090 (and ethio-quote-vowel-always
1091 fidel)))
1092 (insert "'"))
1093 (insert (aref ethio-fidel-to-sera-map ch))
1094 (setq lonec (ethio-lone-consonant-p ch)
1095 fidel t
1096 digit nil))
1098 ;; punctuations or icons
1099 ((or (and (>= ch 353) (<= ch 360)) ; : - :|:
1100 (>= ch 458) ; '' - ?
1101 (and (>= ch 448) (<= ch 452))) ; \~X \~e \~E \~a \~A
1102 (insert (aref ethio-fidel-to-sera-map ch))
1103 (setq lonec nil
1104 fidel nil
1105 digit nil))
1107 ;; now CH must be an ethiopic digit
1109 ;; reduction = 0 or not preceded by Ethiopic number(s)
1110 ((or (= ethio-numeric-reduction 0)
1111 (not digit))
1112 (insert "`" (aref ethio-fidel-to-sera-map ch))
1113 (setq lonec nil
1114 fidel nil
1115 digit t))
1117 ;; reduction = 2 and following 10s, 100s, 10000s
1118 ((and (= ethio-numeric-reduction 2)
1119 (memq ch '(370 379 380)))
1120 (insert (substring (aref ethio-fidel-to-sera-map ch) 1))
1121 (setq lonec nil
1122 fidel nil
1123 digit t))
1125 ;; ordinary following digits
1127 (insert (aref ethio-fidel-to-sera-map ch))
1128 (setq lonec nil
1129 fidel nil
1130 digit t))))
1132 ;; english character. must go to english mode, if not in it.
1133 ((or (and (>= ch ?a) (<= ch ?z))
1134 (and (>= ch ?A) (<= ch ?Z)))
1135 (if (not (eq mode 'english))
1136 (insert "\\~eng "))
1137 (forward-char 1)
1138 (setq mode 'english
1139 lonec nil
1140 fidel nil
1141 digit nil))
1143 ;; ch can appear both in ethiopic section and in english section.
1146 ;; we must decide the mode, if not decided yet
1147 (if (null mode)
1148 (progn
1149 (setq mode
1150 (if secondary
1151 ethio-secondary-language
1152 ethio-primary-language))
1153 (if (eq mode 'english)
1154 (insert "\\~eng ")
1155 (insert flag)
1156 (setq mode 'ethiopic)))) ; tigrigna & amharic --> ethiopic
1158 (cond ; \ , eng-mode , punc , w3 , other
1160 ;; backslash is always quoted
1161 ((= ch ?\\ )
1162 (insert "\\")
1163 (forward-char 1))
1165 ;; nothing to do if in english mode
1166 ((eq mode 'english)
1167 (forward-char 1))
1169 ;; now we must be in ethiopic mode and seeing a non-"\"
1171 ;; ascii punctuations in ethiopic mode
1172 ((looking-at "[,.;:'`?]+")
1173 (insert "\\")
1174 (goto-char (1+ (match-end 0)))) ; because we inserted one byte (\)
1176 ;; skip from "<" to ">" (or from "&" to ";") if called from w3
1177 ((and (boundp 'sera-being-called-by-w3)
1178 sera-being-called-by-w3
1179 (or (= ch ?<) (= ch ?&)))
1180 (search-forward (if (= ch ?<) ">" ";")
1181 nil 0))
1183 ;; neutral character. no need to quote. just skip it.
1185 (forward-char 1)))
1187 (setq lonec nil
1188 fidel nil
1189 digit nil)))
1190 ;; end of main conversion routine
1193 (defun ethio-lone-consonant-p (ethiocode)
1194 "If ETHIOCODE is an Ethiopic lone consonant, return t."
1195 (or (and (< ethiocode 344) (= (% ethiocode 8) 5))
1197 ;; `q `k X `g mW bW GW fW pW wW
1198 (memq ethiocode '(389 405 421 437 440 441 442 443 444 457))))
1200 ;;;###autoload
1201 (defun ethio-fidel-to-sera-mail-or-marker (&optional arg)
1202 "Execute ethio-fidel-to-sera-mail or ethio-fidel-to-sera-marker depending on the current major mode.
1203 If in rmail-mode or in mail-mode, execute the former; otherwise latter."
1205 (interactive "P")
1206 (if (or (eq major-mode 'rmail-mode)
1207 (eq major-mode 'mail-mode))
1208 (ethio-fidel-to-sera-mail)
1209 (ethio-fidel-to-sera-marker arg)))
1211 ;;;###autoload
1212 (defun ethio-fidel-to-sera-mail nil
1213 "Convert FIDEL to SERA to read/write mail and news.
1215 If the body contains at least one Ethiopic character,
1216 1) insert the string \"<sera>\" at the beginning of the body,
1217 2) insert \"</sera>\" at the end of the body, and
1218 3) convert the body into SERA.
1220 The very same procedure applies to the subject field, too."
1222 (interactive)
1223 (let ((buffer-read-only nil)
1224 border)
1225 (save-excursion
1227 ;; follow RFC822 rules instead of looking for a fixed separator
1228 (rfc822-goto-eoh)
1229 (forward-line 1)
1230 (setq border (point))
1232 ;; process body first not to change the border
1233 ;; note that the point is already at the border
1234 (if (re-search-forward "\\ce" nil t)
1235 (progn
1236 (ethio-fidel-to-sera-region border (point-max))
1237 (goto-char border)
1238 (insert "<sera>")
1239 (goto-char (point-max))
1240 (insert "</sera>")))
1242 ;; process subject
1243 (goto-char (point-min))
1244 (if (re-search-forward "^Subject: " border t)
1245 (let ((beg (point))
1246 (end (line-end-position)))
1247 (if (re-search-forward "\\ce" end t)
1248 (progn
1249 (ethio-fidel-to-sera-region beg end)
1250 (goto-char beg)
1251 (insert "<sera>")
1252 (end-of-line)
1253 (insert "</sera>")))))
1255 ;; adjust the rmail marker
1256 (if (eq major-mode 'rmail-mode)
1257 (set-marker
1258 (aref rmail-message-vector (1+ rmail-current-message))
1259 (point-max))))))
1261 ;;;###autoload
1262 (defun ethio-fidel-to-sera-marker (&optional force)
1263 "Convert the regions surrounded by \"<sera>\" and \"</sera>\" from FIDEL to SERA.
1264 The markers \"<sera>\" and \"</sera>\" themselves are not deleted."
1266 (interactive "P")
1267 (if (and buffer-read-only
1268 (not force)
1269 (not (y-or-n-p "Buffer is read-only. Force to convert? ")))
1270 (error ""))
1271 (save-excursion
1272 (goto-char (point-min))
1273 (while (re-search-forward "<sera>" nil t)
1274 (ethio-fidel-to-sera-region
1275 (point)
1276 (if (re-search-forward "</sera>" nil t)
1277 (match-beginning 0)
1278 (point-max))
1280 'force))))
1283 ;; vowel modification
1286 ;;;###autoload
1287 (defun ethio-modify-vowel nil
1288 "Modify the vowel of the FIDEL that is under the cursor."
1289 (interactive)
1290 (let ((ch (following-char))
1291 (composite nil) ; geminated or not
1292 newch base vowel modulo)
1294 (cond
1295 ;; in case of gemination
1296 ((eq (char-charset ch) 'composition)
1297 (setq ch (string-to-char (char-to-string ch))
1298 composite t))
1299 ;; neither gemination nor fidel
1300 ((not (eq (char-charset ch) 'ethiopic))
1301 (error "Not a valid character")))
1303 ;; set frequently referred character features
1304 (setq ch (ethio-char-to-ethiocode ch)
1305 base (* (/ ch 8) 8)
1306 modulo (% ch 8))
1308 (if (or (and (>= ch 344) (<= ch 380)) ;; mYa - `10000
1309 (and (>= ch 448) (<= ch 452)) ;; \~X - \~A
1310 (>= ch 458)) ;; private punctuations
1311 (error "Not a valid character"))
1313 (setq
1314 newch
1315 (cond
1317 ;; first standalone vowels
1318 ((= base 160)
1319 (if (ethio-prefer-amharic-p)
1320 (message "Modify vowel to: [auiAEIoW\"] ")
1321 (message "Modify vowel to: [euiAEIoW\"] "))
1322 (setq vowel (read-char))
1323 (cond
1324 ((= vowel ?e) 160)
1325 ((= vowel ?u) 161)
1326 ((= vowel ?i) 162)
1327 ((= vowel ?A) 163)
1328 ((= vowel ?E) 164)
1329 ((= vowel ?I) 165)
1330 ((= vowel ?o) 166)
1331 ((= vowel ?W) 167)
1332 ((= vowel ?a) (if (ethio-prefer-amharic-p) 160 163))
1333 ((= vowel ?\") (setq composite t) ch)
1334 (t nil)))
1336 ;; second standalone vowels
1337 ((= base 208)
1338 (message "Modify vowel to: [euiaEIo\"] ")
1339 (setq vowel (read-char))
1340 (cond
1341 ((= vowel ?e) 208)
1342 ((= vowel ?u) 209)
1343 ((= vowel ?i) 210)
1344 ((= vowel ?a) 211)
1345 ((= vowel ?E) 212)
1346 ((= vowel ?I) 213)
1347 ((= vowel ?o) 214)
1348 ((= vowel ?\") (setq composite t) ch)
1349 (t nil)))
1351 ;; 12-form consonants, *W* form
1352 ((memq base '(72 88 136 176 192 272)) ; qW QW hW kW KW gW
1353 (message "Modify vowel to: [euiaE'\"] ")
1354 (setq vowel (read-char))
1355 (cond
1356 ((= vowel ?e) base)
1357 ((= vowel ?u) (+ base 5))
1358 ((= vowel ?i) (+ base 2))
1359 ((= vowel ?a) (+ base 3))
1360 ((= vowel ?E) (+ base 4))
1361 ((= vowel ?') (+ base 5))
1362 ((= vowel ?\") (setq composite t) ch)
1363 (t nil)))
1365 ;; extended 12-form consonants, mWa bWa GWa fWa pWa
1366 ((= ch 31) ; mWa
1367 (message "Modify vowel to: [euiaE'\"] ")
1368 (setq vowel (read-char))
1369 (cond
1370 ((= vowel ?e) 392)
1371 ((= vowel ?u) 440)
1372 ((= vowel ?i) 408)
1373 ((= vowel ?a) ch)
1374 ((= vowel ?E) 424)
1375 ((= vowel ?') 440)
1376 ((= vowel ?\") (setq composite t) ch)
1377 (t nil)))
1378 ((= ch 103) ; bWa
1379 (message "Modify vowel to: [euiaE'\"] ")
1380 (setq vowel (read-char))
1381 (cond
1382 ((= vowel ?e) 393)
1383 ((= vowel ?u) 441)
1384 ((= vowel ?i) 409)
1385 ((= vowel ?a) ch)
1386 ((= vowel ?E) 425)
1387 ((= vowel ?') 441)
1388 ((= vowel ?\") (setq composite t) ch)
1389 (t nil)))
1390 ((= ch 287) ; GWa
1391 (message "Modify vowel to: [euiaE'\"] ")
1392 (setq vowel (read-char))
1393 (cond
1394 ((= vowel ?e) 394)
1395 ((= vowel ?u) 442)
1396 ((= vowel ?i) 410)
1397 ((= vowel ?a) ch)
1398 ((= vowel ?E) 426)
1399 ((= vowel ?') 442)
1400 ((= vowel ?\") (setq composite t) ch)
1401 (t nil)))
1402 ((= ch 335) ; fWa
1403 (message "Modify vowel to: [euiaE'\"] ")
1404 (setq vowel (read-char))
1405 (cond
1406 ((= vowel ?e) 395)
1407 ((= vowel ?u) 443)
1408 ((= vowel ?i) 411)
1409 ((= vowel ?a) ch)
1410 ((= vowel ?E) 427)
1411 ((= vowel ?') 443)
1412 ((= vowel ?\") (setq composite t) ch)
1413 (t nil)))
1414 ((= ch 343) ; pWa
1415 (message "Modify vowel to: [euiaE'\"] ")
1416 (setq vowel (read-char))
1417 (cond
1418 ((= vowel ?e) 396)
1419 ((= vowel ?u) 444)
1420 ((= vowel ?i) 412)
1421 ((= vowel ?a) ch)
1422 ((= vowel ?E) 428)
1423 ((= vowel ?') 444)
1424 ((= vowel ?\") (setq composite t) ch)
1425 (t nil)))
1427 ;; extended 12-form consonatns, mW* bW* GW* fW* pW*
1428 ((memq base '(392 408 424 440)) ; *We *Wi *WE *W
1429 (message "Modify vowel to: [eiEau'\"] ")
1430 (setq vowel (read-char))
1431 (cond
1432 ((= vowel ?e) (+ 392 modulo))
1433 ((= vowel ?i) (+ 408 modulo))
1434 ((= vowel ?E) (+ 424 modulo))
1435 ((= vowel ?a) (cond
1436 ((= modulo 0) 31) ; mWa
1437 ((= modulo 1) 103) ; bWa
1438 ((= modulo 2) 287) ; GWa
1439 ((= modulo 3) 335) ; fWa
1440 ((= modulo 4) 343) ; pWa
1441 (t nil))) ; never reach here
1442 ((= vowel ?') (+ 440 modulo))
1443 ((= vowel ?u) (+ 440 modulo))
1444 ((= vowel ?\") (setq composite t) ch)
1445 (t nil)))
1447 ((and (>= ch 453) (<= ch 457)) ; wWe wWi wWa wWE wW
1448 (message "Modify vowel to: [eiaE'u\"] ")
1449 (setq vowel (read-char))
1450 (cond
1451 ((= vowel ?e) 453)
1452 ((= vowel ?i) 454)
1453 ((= vowel ?a) 455)
1454 ((= vowel ?E) 456)
1455 ((= vowel ?') 457)
1456 ((= vowel ?u) 457)
1457 ((= vowel ?\") (setq composite t) ch)
1458 (t nil)))
1460 ;; 7-form consonants, or
1461 ;; first 7 of 8-form consonants
1462 ((<= modulo 6)
1463 (message "Modify vowel to: [euiaE'o\"] ")
1464 (setq vowel (read-char))
1465 (cond
1466 ((= vowel ?e) base)
1467 ((= vowel ?u) (+ base 1))
1468 ((= vowel ?i) (+ base 2))
1469 ((= vowel ?a) (+ base 3))
1470 ((= vowel ?E) (+ base 4))
1471 ((= vowel ?') (+ base 5))
1472 ((= vowel ?o) (+ base 6))
1473 ((= vowel ?\") (setq composite t) ch)
1474 (t nil)))
1476 ;; otherwise
1478 nil)))
1480 (cond
1482 ;; could not get new character
1483 ((null newch)
1484 (error "Invalid vowel"))
1486 ;; vowel changed on a composite Fidel
1487 (composite
1488 (delete-char 1)
1489 (insert
1490 (compose-string
1491 (concat (char-to-string (ethio-ethiocode-to-char newch)) "\e$(3%s\e(B"))))
1493 ;; simple vowel modification
1495 (delete-char 1)
1496 (insert (ethio-ethiocode-to-char newch))))))
1498 (defun ethio-ethiocode-to-char (ethiocode)
1499 (make-char
1500 'ethiopic
1501 (+ (/ ethiocode 94) 33)
1502 (+ (mod ethiocode 94) 33)))
1504 (defun ethio-char-to-ethiocode (ch)
1505 (and (eq (char-charset ch) 'ethiopic)
1506 (let ((char-components (split-char ch)))
1507 (+ (* (- (nth 1 char-components) 33) 94)
1508 (- (nth 2 char-components) 33)))))
1511 ;; space replacement
1514 ;;;###autoload
1515 (defun ethio-replace-space (ch begin end)
1516 "Replace ASCII spaces with Ethiopic word separators in the region.
1518 In the specified region, replace word separators surrounded by two
1519 Ethiopic characters, depending on the first parameter CH, which should
1520 be 1, 2, or 3.
1522 If CH = 1, word separator will be replaced with an ASCII space.
1523 If CH = 2, with two ASCII spaces.
1524 If CH = 3, with the Ethiopic colon-like word separator.
1526 The second and third parameters BEGIN and END specify the region."
1528 (interactive "*cReplace spaces to: 1 (sg col), 2 (dbl col), 3 (Ethiopic)\nr")
1529 (if (not (memq ch '(?1 ?2 ?3)))
1530 (error ""))
1531 (save-excursion
1532 (save-restriction
1533 (narrow-to-region begin end)
1535 (cond
1536 ((= ch ?1)
1537 ;; an Ethiopic word separator --> an ASCII space
1538 (goto-char (point-min))
1539 (while (search-forward "\e$(3$h\e(B" nil t)
1540 (replace-match " " nil t))
1542 ;; two ASCII spaces between Ethiopic characters --> an ASCII space
1543 (goto-char (point-min))
1544 (while (re-search-forward "\\(\\ce\\) \\(\\ce\\)" nil t)
1545 (replace-match "\\1 \\2")
1546 (goto-char (match-beginning 2))))
1548 ((= ch ?2)
1549 ;; An Ethiopic word separator --> two ASCII spaces
1550 (goto-char (point-min))
1551 (while (search-forward "\e$(3$h\e(B" nil t)
1552 (replace-match " "))
1554 ;; An ASCII space between Ethiopic characters --> two ASCII spaces
1555 (goto-char (point-min))
1556 (while (re-search-forward "\\(\\ce\\) \\(\\ce\\)" nil t)
1557 (replace-match "\\1 \\2")
1558 (goto-char (match-beginning 2))))
1561 ;; One or two ASCII spaces between Ethiopic characters
1562 ;; --> An Ethiopic word separator
1563 (goto-char (point-min))
1564 (while (re-search-forward "\\(\\ce\\) ?\\(\\ce\\)" nil t)
1565 (replace-match "\\1\e$(3$h\e(B\\2")
1566 (goto-char (match-beginning 2)))
1568 ;; Three or more ASCII spaces between Ethiopic characters
1569 ;; --> An Ethiopic word separator + (N - 2) ASCII spaces
1570 (goto-char (point-min))
1571 (while (re-search-forward "\\(\\ce\\) \\( *\\ce\\)" nil t)
1572 (replace-match "\\1\e$(3$h\e(B\\2")
1573 (goto-char (match-beginning 2))))))))
1576 ;; special icons
1579 ;;;###autoload
1580 (defun ethio-input-special-character (arg)
1581 "Allow the user to input special characters."
1582 (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")
1583 (cond
1584 ((= arg ?1)
1585 (insert "\e$(3%j\e(B"))
1586 ((= arg ?2)
1587 (insert "\e$(3%k\e(B"))
1588 ((= arg ?3)
1589 (insert "\e$(3%l\e(B"))
1590 ((= arg ?4)
1591 (insert "\e$(3%m\e(B"))
1592 ((= arg ?5)
1593 (insert "\e$(3%i\e(B"))
1595 (error ""))))
1598 ;; TeX support
1601 (defconst ethio-fidel-to-tex-map
1602 [ "heG" "huG" "hiG" "haG" "hEG" "hG" "hoG" "" ;; 0 - 7
1603 "leG" "luG" "liG" "laG" "lEG" "lG" "loG" "lWaG" ;; 8
1604 "HeG" "HuG" "HiG" "HaG" "HEG" "HG" "HoG" "HWaG" ;; 16
1605 "meG" "muG" "miG" "maG" "mEG" "mG" "moG" "mWaG" ;; 24
1606 "sseG" "ssuG" "ssiG" "ssaG" "ssEG" "ssG" "ssoG" "ssWaG" ;; 32
1607 "reG" "ruG" "riG" "raG" "rEG" "rG" "roG" "rWaG" ;; 40
1608 "seG" "suG" "siG" "saG" "sEG" "sG" "soG" "sWaG" ;; 48
1609 "xeG" "xuG" "xiG" "xaG" "xEG" "xG" "xoG" "xWaG" ;; 56
1610 "qeG" "quG" "qiG" "qaG" "qEG" "qG" "qoG" "" ;; 64
1611 "qWeG" "" "qWiG" "qWaG" "qWEG" "qWG" "" "" ;; 72
1612 "QeG" "QuG" "QiG" "QaG" "QEG" "QG" "QoG" "" ;; 80
1613 "QWeG" "" "QWiG" "QWaG" "QWEG" "QWG" "" "" ;; 88
1614 "beG" "buG" "biG" "baG" "bEG" "bG" "boG" "bWaG" ;; 96
1615 "veG" "vuG" "viG" "vaG" "vEG" "vG" "voG" "vWaG" ;; 104
1616 "teG" "tuG" "tiG" "taG" "tEG" "tG" "toG" "tWaG" ;; 112
1617 "ceG" "cuG" "ciG" "caG" "cEG" "cG" "coG" "cWaG" ;; 120
1618 "hheG" "hhuG" "hhiG" "hhaG" "hhEG" "hhG" "hhoG" "" ;; 128
1619 "hWeG" "" "hWiG" "hWaG" "hWEG" "hWG" "" "" ;; 136
1620 "neG" "nuG" "niG" "naG" "nEG" "nG" "noG" "nWaG" ;; 144
1621 "NeG" "NuG" "NiG" "NaG" "NEG" "NG" "NoG" "NWaG" ;; 152
1622 "eG" "uG" "iG" "AG" "EG" "IG" "oG" "eaG" ;; 160
1623 "keG" "kuG" "kiG" "kaG" "kEG" "kG" "koG" "" ;; 168
1624 "kWeG" "" "kWiG" "kWaG" "kWEG" "kWG" "" "" ;; 176
1625 "KeG" "KuG" "KiG" "KaG" "KEG" "KG" "KoG" "" ;; 184
1626 "KWeG" "" "KWiG" "KWaG" "KWEG" "KWG" "" "" ;; 192
1627 "weG" "wuG" "wiG" "waG" "wEG" "wG" "woG" "" ;; 200
1628 "eeG" "uuG" "iiG" "aaG" "EEG" "IIG" "ooG" "" ;; 208
1629 "zeG" "zuG" "ziG" "zaG" "zEG" "zG" "zoG" "zWaG" ;; 216
1630 "ZeG" "ZuG" "ZiG" "ZaG" "ZEG" "ZG" "ZoG" "ZWaG" ;; 224
1631 "yeG" "yuG" "yiG" "yaG" "yEG" "yG" "yoG" "yWaG" ;; 232
1632 "deG" "duG" "diG" "daG" "dEG" "dG" "doG" "dWaG" ;; 240
1633 "DeG" "DuG" "DiG" "DaG" "DEG" "DG" "DoG" "DWaG" ;; 248
1634 "jeG" "juG" "jiG" "jaG" "jEG" "jG" "joG" "jWaG" ;; 256
1635 "geG" "guG" "giG" "gaG" "gEG" "gG" "goG" "" ;; 264
1636 "gWeG" "" "gWiG" "gWaG" "gWEG" "gWG" "" "" ;; 272
1637 "GeG" "GuG" "GiG" "GaG" "GEG" "GG" "GoG" "GWaG" ;; 280
1638 "TeG" "TuG" "TiG" "TaG" "TEG" "TG" "ToG" "TWaG" ;; 288
1639 "CeG" "CuG" "CiG" "CaG" "CEG" "CG" "CoG" "CWaG" ;; 296
1640 "PeG" "PuG" "PiG" "PaG" "PEG" "PG" "PoG" "PWaG" ;; 304
1641 "SeG" "SuG" "SiG" "SaG" "SEG" "SG" "SoG" "SWaG" ;; 312
1642 "SSeG" "SSuG" "SSiG" "SSaG" "SSEG" "SSG" "SSoG" "" ;; 320
1643 "feG" "fuG" "fiG" "faG" "fEG" "fG" "foG" "fWaG" ;; 328
1644 "peG" "puG" "piG" "paG" "pEG" "pG" "poG" "pWaG" ;; 336
1645 "mYaG" "rYaG" "fYaG" "" "" "" "" "" ;; 344
1646 "" "spaceG" "periodG" "commaG" ;; 352
1647 "semicolonG" "colonG" "precolonG" "oldqmarkG" ;; 356
1648 "pbreakG" "andG" "huletG" "sostG" "aratG" "amstG" "sadstG" "sabatG" ;; 360
1649 "smntG" "zeteNG" "asrG" "heyaG" "selasaG" "arbaG" "hemsaG" "slsaG" ;; 368
1650 "sebaG" "semanyaG" "zeTanaG" "metoG" "asrxiG" "" "" "" ;; 376
1651 "qqeG" "qquG" "qqiG" "qqaG" "qqEG" "qqG" "qqoG" "" ;; 384
1652 "mWeG" "bWeG" "GWeG" "fWeG" "pWeG" "" "" "" ;; 392
1653 "kkeG" "kkuG" "kkiG" "kkaG" "kkEG" "kkG" "kkoG" "" ;; 400
1654 "mWiG" "bWiG" "GWiG" "fWiG" "pWiG" "" "" "" ;; 408
1655 "XeG" "XuG" "GXiG" "XaG" "XEG" "XG" "XoG" "" ;; 416
1656 "mWEG" "bWEG" "GWEG" "fWEG" "pWEG" "" "" "" ;; 424
1657 "ggeG" "gguG" "ggiG" "ggaG" "ggEG" "ggG" "ggoG" "" ;; 432
1658 "mWG" "bWG" "GWG" "fWG" "pWG" "" "" "" ;; 440
1659 "ornamentG" "flandG" "iflandG" "africaG" ;; 448
1660 "iafricaG" "wWeG" "wWiG" "wWaG" ;; 452
1661 "wWEG" "wWG" "" "slaqG" "dotG" "lquoteG" "rquoteG" "qmarkG" ]) ;; 456
1664 ;; To make tex-to-fidel mapping.
1665 ;; The following code makes
1666 ;; (get 'ethio-tex-command-he 'ethio-fidel-char) ==> ?\e$(3!!\e(B
1667 ;; etc.
1670 (let ((i 0) str)
1671 (while (< i (length ethio-fidel-to-tex-map))
1672 (setq str (aref ethio-fidel-to-tex-map i))
1673 (if (not (string= str ""))
1674 (put
1675 (intern (concat "ethio-tex-command-" (aref ethio-fidel-to-tex-map i)))
1676 'ethio-fidel-char
1677 (ethio-ethiocode-to-char i)))
1678 (setq i (1+ i))))
1680 ;;;###autoload
1681 (defun ethio-fidel-to-tex-buffer nil
1682 "Convert each fidel characters in the current buffer into a fidel-tex command.
1683 Each command is always surrounded by braces."
1684 (interactive)
1685 (let ((buffer-read-only nil))
1687 ;; Isolated gemination marks need special treatement
1688 (goto-char (point-min))
1689 (while (search-forward "\e$(3%s\e(B" nil t)
1690 (replace-match "\\geminateG{}" t t))
1692 ;; First, decompose geminations
1693 ;; Here we assume that each composed character consists of
1694 ;; one Ethiopic character and the Ethiopic gemination mark.
1695 (decompose-region (point-min) (point-max))
1697 ;; Special treatment for geminated characters
1698 ;; The geminated character (la'') will be "\geminateG{\la}".
1699 (goto-char (point-min))
1700 (while (search-forward "\e$(3%s\e(B" nil t)
1701 (delete-backward-char 1)
1702 (backward-char 1)
1703 (insert "\\geminateG")
1704 (forward-char 1))
1706 ;; Ethiopic characters to TeX macros
1707 (goto-char (point-min))
1708 (while (re-search-forward "\\ce" nil t)
1709 (insert
1710 "{\\"
1711 (aref ethio-fidel-to-tex-map
1712 (prog1 (ethio-char-to-ethiocode (preceding-char))
1713 (backward-delete-char 1)))
1714 "}"))
1715 (goto-char (point-min))
1716 (set-buffer-modified-p nil)))
1718 ;;;###autoload
1719 (defun ethio-tex-to-fidel-buffer nil
1720 "Convert fidel-tex commands in the current buffer into fidel chars."
1721 (interactive)
1722 (let ((buffer-read-only nil)
1723 (p) (ch))
1725 ;; Special treatment for gemination
1726 ;; "\geminateG{\la}" or "\geminateG{{\la}}" will be "\la\e$(3%s\e(B"
1727 ;; "\geminateG{}" remains unchanged.
1728 (goto-char (point-min))
1729 (while (re-search-forward "\\\\geminateG{\\(\\\\[a-zA-Z]+\\)}" nil t)
1730 (replace-match "\\1\e$(3%s\e(B"))
1732 ;; TeX macros to Ethiopic characters
1733 (goto-char (point-min))
1734 (while (search-forward "\\" nil t)
1735 (setq p (point))
1736 (skip-chars-forward "a-zA-Z")
1737 (setq ch
1738 (get (intern (concat "ethio-tex-command-"
1739 (buffer-substring p (point))))
1740 'ethio-fidel-char))
1741 (if ch
1742 (progn
1743 (delete-region (1- p) (point)) ; don't forget the preceding "\"
1744 (if (and (= (preceding-char) ?{)
1745 (= (following-char) ?}))
1746 (progn
1747 (backward-delete-char 1)
1748 (delete-char 1)))
1749 (insert ch))))
1751 ;; compose geminated characters
1752 (goto-char (point-min))
1753 (while (re-search-forward "\\ce\e$(3%s\e(B" nil 0)
1754 (compose-region
1755 (save-excursion (backward-char 2) (point))
1756 (point)))
1758 ;; Now it's time to convert isolated gemination marks.
1759 (goto-char (point-min))
1760 (while (search-forward "\\geminateG{}" nil t)
1761 (replace-match "\e$(3%s\e(B"))
1763 (goto-char (point-min))
1764 (set-buffer-modified-p nil)))
1767 ;; Java support
1770 ;;;###autoload
1771 (defun ethio-fidel-to-java-buffer nil
1772 "Convert Ethiopic characters into the Java escape sequences.
1774 Each escape sequence is of the form \uXXXX, where XXXX is the
1775 character's codepoint (in hex) in Unicode.
1777 If `ethio-java-save-lowercase' is non-nil, use [0-9a-f].
1778 Otherwise, [0-9A-F]."
1779 (let ((ucode))
1781 ;; first, decompose geminations
1782 (decompose-region (point-min) (point-max))
1784 (goto-char (point-min))
1785 (while (re-search-forward "\\ce" nil t)
1786 (setq ucode (+ ?\x1200 (ethio-char-to-ethiocode (preceding-char))))
1787 (if (> ucode ?\x13bc)
1788 (setq ucode (+ ucode 59952)))
1789 (delete-backward-char 1)
1790 (if ethio-java-save-lowercase
1791 (insert (format "\\u%4x" ucode))
1792 (insert (upcase (format "\\u%4x" ucode)))))))
1794 ;;;###autoload
1795 (defun ethio-java-to-fidel-buffer nil
1796 "Convert the Java escape sequences into corresponding Ethiopic characters."
1797 (let ((ucode))
1798 (goto-char (point-min))
1799 (while (re-search-forward "\\\\u\\([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\\)" nil t)
1800 (setq ucode
1801 (read
1802 (concat
1803 "?\\x"
1804 (buffer-substring (match-beginning 1) (match-end 1)))))
1805 (cond
1806 ((and (>= ucode ?\x1200) (<= ucode ?\x13bc))
1807 (replace-match "")
1808 (insert (ethio-ethiocode-to-char (- ucode ?\x1200))))
1809 ((and (>= ucode ?\xfdf1) (<= ucode ?\xfdff))
1810 (replace-match "")
1811 (insert (ethio-ethiocode-to-char (- ucode 64560))))
1813 nil)))
1815 ;; gemination
1816 (goto-char (point-min))
1817 (while (re-search-forward "\\ce\e$(3%s\e(B" nil 0)
1818 (compose-region
1819 (save-excursion (backward-char 2) (point))
1820 (point)))
1824 ;; file I/O hooks
1827 ;;;###autoload
1828 (defun ethio-find-file nil
1829 "Transcribe file content into Ethiopic dependig on filename suffix."
1830 (cond
1832 ((string-match "\\.sera$" (buffer-file-name))
1833 (save-excursion
1834 (ethio-sera-to-fidel-buffer nil 'force)
1835 (set-buffer-modified-p nil)))
1837 ((string-match "\\.html$" (buffer-file-name))
1838 (let ((sera-being-called-by-w3 t))
1839 (save-excursion
1840 (ethio-sera-to-fidel-marker 'force)
1841 (goto-char (point-min))
1842 (while (re-search-forward "&[lr]aquote;" nil t)
1843 (if (= (char-after (1+ (match-beginning 0))) ?l)
1844 (replace-match "\e$(3%v\e(B")
1845 (replace-match "\e$(3%w\e(B")))
1846 (set-buffer-modified-p nil))))
1848 ((string-match "\\.tex$" (buffer-file-name))
1849 (save-excursion
1850 (ethio-tex-to-fidel-buffer)
1851 (set-buffer-modified-p nil)))
1853 ((string-match "\\.java$" (buffer-file-name))
1854 (save-excursion
1855 (ethio-java-to-fidel-buffer)
1856 (set-buffer-modified-p nil)))
1859 nil)))
1861 ;;;###autoload
1862 (defun ethio-write-file nil
1863 "Transcribe Ethiopic characters in ASCII depending on the file extension."
1864 (cond
1866 ((string-match "\\.sera$" (buffer-file-name))
1867 (save-excursion
1868 (ethio-fidel-to-sera-buffer nil 'force)
1869 (goto-char (point-min))
1870 (ethio-record-user-preference)
1871 (set-buffer-modified-p nil)))
1873 ((string-match "\\.html$" (buffer-file-name))
1874 (save-excursion
1875 (let ((sera-being-called-by-w3 t)
1876 (lq (aref ethio-fidel-to-sera-map 461))
1877 (rq (aref ethio-fidel-to-sera-map 462)))
1878 (aset ethio-fidel-to-sera-map 461 "&laquote;")
1879 (aset ethio-fidel-to-sera-map 462 "&raquote;")
1880 (ethio-fidel-to-sera-marker 'force)
1881 (goto-char (point-min))
1882 (if (search-forward "<sera>" nil t)
1883 (ethio-record-user-preference))
1884 (aset ethio-fidel-to-sera-map 461 lq)
1885 (aset ethio-fidel-to-sera-map 462 rq)
1886 (set-buffer-modified-p nil))))
1888 ((string-match "\\.tex$" (buffer-file-name))
1889 (save-excursion
1890 (ethio-fidel-to-tex-buffer)
1891 (set-buffer-modified-p nil)))
1893 ((string-match "\\.java$" (buffer-file-name))
1894 (save-excursion
1895 (ethio-fidel-to-java-buffer)
1896 (set-buffer-modified-p nil)))
1899 nil)))
1901 (defun ethio-record-user-preference nil
1902 (if (looking-at "\\\\~\\(tir?\\|amh?\\) ")
1903 (goto-char (match-end 0))
1904 (insert (if (ethio-prefer-amharic-p) "\\~amh " "\\~tir ")))
1905 (insert (if ethio-use-colon-for-colon "\\~-: " "\\~`: ")
1906 (if ethio-use-three-dot-question "\\~`| " "\\~`? ")))
1909 ;; Ethiopic word separator vs. ASCII space
1912 (defvar ethio-prefer-ascii-space t)
1913 (make-variable-buffer-local 'ethio-prefer-ascii-space)
1915 (defun ethio-toggle-space nil
1916 "Toggle ASCII space and Ethiopic separator for keyboard input."
1917 (interactive)
1918 (setq ethio-prefer-ascii-space
1919 (not ethio-prefer-ascii-space))
1920 (if (equal current-input-method "ethiopic")
1921 (setq current-input-method-title (quail-title)))
1922 (force-mode-line-update))
1924 (defun ethio-insert-space (arg)
1925 "Insert ASCII spaces or Ethiopic word separators depending on context.
1927 If the current word separator (indicated in mode-line) is the ASCII space,
1928 insert an ASCII space. With ARG, insert that many ASCII spaces.
1930 If the current word separator is the colon-like Ethiopic word
1931 separator and the point is preceded by `an Ethiopic punctuation mark
1932 followed by zero or more ASCII spaces', then insert also an ASCII
1933 space. With ARG, insert that many ASCII spaces.
1935 Otherwise, insert a colon-like Ethiopic word separator. With ARG, insert that
1936 many Ethiopic word separators."
1938 (interactive "*p")
1939 (cond
1940 (ethio-prefer-ascii-space
1941 (insert-char 32 arg))
1942 ((save-excursion
1943 (skip-chars-backward " ")
1944 (memq (preceding-char)
1945 '(?\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)))
1946 (insert-char 32 arg))
1948 (insert-char ?\e$(3$h\e(B arg))))
1950 (defun ethio-insert-ethio-space (arg)
1951 "Insert the Ethiopic word delimiter (the colon-like character).
1952 With ARG, insert that many delimiters."
1953 (interactive "*p")
1954 (insert-char ?\e$(3$h\e(B arg))
1957 ;; Ethiopic punctuation vs. ASCII punctuation
1960 (defvar ethio-prefer-ascii-punctuation nil)
1961 (make-variable-buffer-local 'ethio-prefer-ascii-punctuation)
1963 (defun ethio-toggle-punctuation nil
1964 "Toggle Ethiopic punctuations and ASCII punctuations for keyboard input."
1965 (interactive)
1966 (setq ethio-prefer-ascii-punctuation
1967 (not ethio-prefer-ascii-punctuation))
1968 (let* ((keys '("." ".." "..." "," ",," ";" ";;" ":" "::" ":::" "*" "**"))
1969 (puncs
1970 (if ethio-prefer-ascii-punctuation
1971 '(?. [".."] ["..."] ?, [",,"] ?\; [";;"] ?: ["::"] [":::"] ?* ["**"])
1972 '(?\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))))
1973 (while keys
1974 (quail-defrule (car keys) (car puncs) "ethiopic")
1975 (setq keys (cdr keys)
1976 puncs (cdr puncs)))
1977 (if (equal current-input-method "ethiopic")
1978 (setq current-input-method-title (quail-title)))
1979 (force-mode-line-update)))
1982 ;; Gemination
1985 (defun ethio-gemination nil
1986 "Compose the character before the point with the Ethiopic gemination mark.
1987 If the character is already composed, decompose it and remove the gemination
1988 mark."
1989 (interactive "*")
1990 (cond
1991 ((eq (char-charset (preceding-char)) 'ethiopic)
1992 (insert "\e$(3%s\e(B")
1993 (compose-region
1994 (save-excursion (backward-char 2) (point))
1995 (point))
1996 (forward-char 1))
1997 ((eq (char-charset (preceding-char)) 'leading-code-composition)
1998 (decompose-region
1999 (save-excursion (backward-char 1) (point))
2000 (point))
2001 (delete-backward-char 1))
2003 (error ""))))
2006 (provide 'ethio-util)
2008 ;;; arch-tag: c8feb3d6-39bf-4b0a-b6ef-26f03fbc8140
2009 ;;; ethio-util.el ends here