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