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