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