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