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