Mercurial > emacs
annotate lisp/international/robin.el @ 91554:8d25c5588e59
Update copyright years and GPL version.
author | Glenn Morris <rgm@gnu.org> |
---|---|
date | Wed, 06 Feb 2008 04:22:18 +0000 |
parents | 3053d89875bb |
children | 889bc336b89b |
rev | line source |
---|---|
90124 | 1 ;;; robin.el --- yet another input method (smaller than quail) |
2 | |
91435
3053d89875bb
Update copyright years and GPL version.
Glenn Morris <rgm@gnu.org>
parents:
90279
diff
changeset
|
3 ;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 |
90124 | 4 ;; National Institute of Advanced Industrial Science and Technology (AIST) |
90279 | 5 ;; Registration Number: H15PRO110 |
90124 | 6 |
7 ;; Author: TAKAHASHI Naoto <ntakahas@m17n.org> | |
8 ;; Keywords: mule, multilingual, input method | |
9 | |
91435
3053d89875bb
Update copyright years and GPL version.
Glenn Morris <rgm@gnu.org>
parents:
90279
diff
changeset
|
10 ;; This file is part of GNU Emacs. |
3053d89875bb
Update copyright years and GPL version.
Glenn Morris <rgm@gnu.org>
parents:
90279
diff
changeset
|
11 |
3053d89875bb
Update copyright years and GPL version.
Glenn Morris <rgm@gnu.org>
parents:
90279
diff
changeset
|
12 ;; GNU Emacs is free software; you can redistribute it and/or |
90124 | 13 ;; modify it under the terms of the GNU General Public License as |
91435
3053d89875bb
Update copyright years and GPL version.
Glenn Morris <rgm@gnu.org>
parents:
90279
diff
changeset
|
14 ;; published by the Free Software Foundation; either version 3, or (at |
90124 | 15 ;; your option) any later version. |
16 | |
17 ;; This program is distributed in the hope that it will be useful, but | |
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
20 ;; General Public License for more details. | |
21 | |
22 ;; You should have received a copy of the GNU General Public License | |
91435
3053d89875bb
Update copyright years and GPL version.
Glenn Morris <rgm@gnu.org>
parents:
90279
diff
changeset
|
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
3053d89875bb
Update copyright years and GPL version.
Glenn Morris <rgm@gnu.org>
parents:
90279
diff
changeset
|
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
3053d89875bb
Update copyright years and GPL version.
Glenn Morris <rgm@gnu.org>
parents:
90279
diff
changeset
|
25 ;; Boston, MA 02110-1301, USA. |
90124 | 26 |
27 ;;; Comentary: | |
28 | |
29 ;; Functionalities | |
30 ;; --------------- | |
31 | |
32 ;; Robin is a new input method for GNU Emacs. It has three | |
33 ;; functionalities: | |
34 | |
35 ;; 1. It serves as a simple input method. When the user types an ASCII | |
36 ;; key sequence, robin converts it into a string. This functionality | |
37 ;; is most likely used to input non-ASCII characters. | |
38 | |
39 ;; 2. It converts existing buffer substring into another string. | |
40 ;; This functionality is similar to the 1. above, but the input is | |
41 ;; buffer substring rather than key strokes. | |
42 | |
43 ;; 3. It offers reverse conversion. Each character produced by a | |
44 ;; robin rule can hold the original ASCII sequence as a | |
45 ;; char-code-property. | |
46 | |
47 | |
48 ;; How to define conversion rules | |
49 ;; ------------------------------ | |
50 | |
51 ;; Each conversion rule belongs to a robin package. A robin package is | |
52 ;; identified by a string called package name. Use robin-define-package | |
53 ;; to define a robin package. | |
54 | |
55 ;; (robin-define-package NAME DOCTSTRING | |
56 ;; (INPUT1 OUPUT1) | |
57 ;; (INPUT2 OUPUT2) | |
58 ;; ...) | |
59 | |
60 ;; NAME is a string identifying the robin package. It often starts with a | |
61 ;; language name and followed by a method name. For example, | |
62 ;; french-postfix, greek-prefix, etc. | |
63 | |
64 ;; DOCSTRING is a documentation string for the robin method. | |
65 | |
66 ;; Each INPUTn is a string. It represents a transliteration of the | |
67 ;; corresponding OUTPUTn. | |
68 | |
69 ;; Each OUTPUTn is a string or a character that is to be inserted as the | |
70 ;; result of conversion. | |
71 | |
72 ;; Neither INPUT* nor OUTPUT* are evaluated. Do not use a variable or a | |
73 ;; function in those parts. Instead, use a string or character literal | |
74 ;; directly. | |
75 | |
76 ;; If multiple rules have the same input pattern but different output | |
77 ;; patterns, only the latest definition is effective. | |
78 | |
79 | |
80 ;; Example | |
81 ;; ------- | |
82 | |
83 ;; (robin-define-package "german-example" | |
84 ;; "An example for German | |
85 | |
86 ;; AE -> Ä OE -> Ö UE -> Ü | |
87 ;; ae -> ä oe -> ö ue -> ü ss -> ß | |
88 | |
89 ;; Repeat E or S to input itself. | |
90 | |
91 ;; AEE -> AE OEE -> OE UEE -> UE | |
92 ;; aee -> ae oee -> oe uee -> ue sss -> ss" | |
93 | |
94 ;; ("AE" ?Ä) | |
95 ;; ("OE" ?Ö) | |
96 ;; ("UE" ?Ü) | |
97 ;; ("ae" ?ä) | |
98 ;; ("oe" ?ö) | |
99 ;; ("ue" ?ü) | |
100 ;; ("ss" ?ß) | |
101 | |
102 ;; ("AEE" "AE") | |
103 ;; ("OEE" "OE") | |
104 ;; ("UEE" "UE") | |
105 ;; ("aee" "ae") | |
106 ;; ("oee" "oe") | |
107 ;; ("uee" "ue") | |
108 ;; ("sss" "ss") | |
109 ;; ) | |
110 | |
111 | |
112 ;; Using robin as an input method | |
113 ;; ------------------------------ | |
114 | |
115 ;; To use a defined robin package as an input method, register it with | |
116 ;; the register-input-method function. For example, | |
117 | |
118 ;; (register-input-method | |
119 ;; "german-example" | |
120 ;; "german" | |
121 ;; 'robin-use-package | |
122 ;; "de" | |
123 ;; "An example for German") | |
124 | |
125 ;; The first argument is the robin package name. | |
126 | |
127 ;; The second argument is the language environment for which this robin | |
128 ;; package is used. | |
129 | |
130 ;; Use the symbol `robin-use-package' as the third argument. | |
131 | |
132 ;; The fourth argument is the prompt that appears in modeline when this | |
133 ;; input method is active. | |
134 | |
135 ;; The fifth argument is a documentation string; it may or may not be | |
136 ;; identical to the one that you specified in robin-define-package. | |
137 | |
138 ;; You can activate the robin input method by typing | |
139 | |
140 ;; C-u C-\ german-example RET | |
141 | |
142 ;; Just like a quail package, only C-\ suffices for subsequent | |
143 ;; invocation. | |
144 | |
145 | |
146 ;; Using robin as a buffer translator | |
147 ;; ---------------------------------- | |
148 | |
149 ;; To transliterate buffer substring, use the following functions. | |
150 | |
151 ;; (robin-convert-buffer &optional name) | |
152 | |
153 ;; Convert the content of current buffer using a robin package. | |
154 | |
155 ;; NAME, if given, is a string specifying a robin package. If NAME is | |
156 ;; not given or nil, the value of `robin-current-package-name' is used. | |
157 | |
158 ;; (robin-convert-region begin end &optional name) | |
159 | |
160 ;; Convert the region using a robin package. | |
161 | |
162 ;; NAME, if given, is a string specifying a robin package. If NAME is | |
163 ;; not given or nil, the value of `robin-current-package-name' is used. | |
164 | |
165 | |
166 ;; Reverse conversion | |
167 ;; ------------------ | |
168 | |
169 ;; If the output pattern defined in a robin rule is a character, robin | |
170 ;; gives to the character a char-code-property whose key is the symbol | |
171 ;; representation of the robin package name and whose value is the input | |
172 ;; pattern of that character. For example, with the "german-example" | |
173 ;; definition above, | |
174 | |
175 ;; (get-char-code-property ?Ä 'german-example) => "AE" | |
176 | |
177 ;; etc. | |
178 | |
179 ;; If you do not want to assign a char-code-property to a character, use | |
180 ;; a string of length one as the output pattern, e.g. | |
181 | |
182 ;; (robin-define-package "german-example2" | |
183 ;; "Another example for German." | |
184 | |
185 ;; ("AE" "Ä") | |
186 ;; ("OE" "Ö") | |
187 ;; ...) | |
188 | |
189 ;; Then | |
190 | |
191 ;; (get-char-code-property ?Ä 'german-example2) => nil | |
192 | |
193 ;; etc. | |
194 | |
195 ;; If multiple input patterns in a robin package generate the same | |
196 ;; character, the lastly used input pattern is given as the value of the | |
197 ;; char-code-property. | |
198 | |
199 ;; There are two functions for reverse conversion. | |
200 | |
201 ;; (robin-invert-buffer &optional name) | |
202 | |
203 ;; Apply reverse conversion to the content of current buffer. NAME, if | |
204 ;; given, is a string specifying a robin package. If NAME is not given | |
205 ;; or nil, the value of `robin-current-package-name' is used. | |
206 | |
207 ;; (robin-invert-region begin end &optional name) | |
208 | |
209 ;; Apply reverse conversion to the region. NAME, if given, is a string | |
210 ;; specifying a robin package. If NAME is not given or nil, the value of | |
211 ;; `robin-current-package-name' is used. | |
212 | |
213 | |
214 ;; Modifying an existing rule | |
215 ;; -------------------------- | |
216 | |
217 ;; Use the robin-modify-package function to modify a rule already defined | |
218 ;; in a Robin package. | |
219 | |
220 ;; (robin-modify-package name input output) | |
221 | |
222 ;; Change a rule in an already defined Robin package. | |
223 ;; NAME is the string specifying a robin package. | |
224 ;; INPUT is a string that specifies the input pattern. | |
225 ;; OUTPUT is either a character or a string to be generated. | |
226 | |
227 | |
228 ;; The name of the game | |
229 ;; -------------------- | |
230 | |
231 ;; As stated in Murphy's law, it took longer than expected to develop the | |
232 ;; very first version of Japanese input subsystem in NEmacs (Nihongo | |
233 ;; Emacs). So the subsystem was named "TAMAGO", which is an acronym of | |
234 ;; "TAkusan Matasete GOmennasai" (Sorry to have kept you waiting so | |
235 ;; long). "Tamago" as a Japanese word means "egg", so the word "egg" was | |
236 ;; also used for related filenames and function names. | |
237 | |
238 ;; Since it was designed to input CJK characters, Egg was rather big as a | |
239 ;; subsystem. So later in Mule (Multilingual Enhancement to GNU Emacs), | |
240 ;; we designed and implemented a smaller input subsystem. We had to give | |
241 ;; it a name. "So, what's smaller than an egg?" "A quail egg, of | |
242 ;; course." Therefore it was named "quail". | |
243 | |
244 ;; As time went by, quail became more and more complicated. That | |
245 ;; tendency was inevitable as long as we support CJK input. However, if | |
246 ;; we can limit ourselves to non-CJK characters, a much simpler | |
247 ;; transliteration mechanism suffices. So I wrote "robin", whose name | |
248 ;; was chosen because a robin is smaller than a quail. I could name it | |
249 ;; "hummingbird" or "nightingale", but those spellings seemed too long. | |
250 | |
251 | |
252 ;;; Code: | |
253 | |
254 (defvar robin-package-alist nil | |
255 "List of robin packages. | |
256 A robin pacakge is of the form (NAME DOCSTRING &rest RULES). | |
257 NAME is a string specifying a particular robin package. | |
258 DOCSTRING is a documentation string for the robin package. | |
259 | |
260 RULE is of the form (KEY OUTPUT &rest rules). | |
261 KEY is a string. | |
262 OUTPUT is a character or a string. | |
263 For example, if you evaluate the following, | |
264 | |
265 (robin-define-package \"test\" \"Uppercase input characters\" | |
266 (\"a\" \"A\") | |
267 (\"ab\" \"AB\") | |
268 (\"ac\" \"AC\") | |
269 (\"acd\" \"ACD\") | |
270 (\"ace\" \"ACE\") | |
271 (\"b\" \"B\")) | |
272 | |
273 this robin package will be the following. | |
274 | |
275 (\"test\" \"Uppercase input characters\" | |
276 (?a \"A\" | |
277 (?b \"AB\") | |
278 (?c \"AC\" | |
279 (?d \"ACD\") | |
280 (?e \"ACE\"))) | |
281 (?b \"B\")) | |
282 ") | |
283 | |
284 ;;;###autoload | |
285 (defmacro robin-define-package (name docstring &rest rules) | |
286 "Define a robin package. | |
287 | |
288 NAME is the string of this robin package. | |
289 DOCSTRING is the documentation string of this robin package. | |
290 Each RULE is of the form (INPUT OUTPUT) where INPUT is a string and | |
291 OUTPUT is either a character or a string. RULES are not evaluated. | |
292 | |
293 If there already exists a robin package whose name is NAME, the new | |
294 one replaces the old one." | |
295 | |
90206
4857b75944d3
(robin-define-package): Delete redundant
Kenichi Handa <handa@m17n.org>
parents:
90204
diff
changeset
|
296 (let ((iname (intern name)) |
90124 | 297 (new (list name "")) ; "" as a fake output |
90220
26b71cf7f16d
(robin-define-package): Be sure to call put-char-code-property.
Kenichi Handa <handa@m17n.org>
parents:
90206
diff
changeset
|
298 input output pairs) |
90124 | 299 (dolist (r rules) |
300 (setq input (car r) | |
301 output (cadr r)) | |
302 (robin-add-rule name new input output) | |
303 (cond | |
304 ((not (stringp input)) | |
305 (error "Bad input sequence %S" r)) | |
90220
26b71cf7f16d
(robin-define-package): Be sure to call put-char-code-property.
Kenichi Handa <handa@m17n.org>
parents:
90206
diff
changeset
|
306 ((characterp output) |
26b71cf7f16d
(robin-define-package): Be sure to call put-char-code-property.
Kenichi Handa <handa@m17n.org>
parents:
90206
diff
changeset
|
307 (setq pairs |
26b71cf7f16d
(robin-define-package): Be sure to call put-char-code-property.
Kenichi Handa <handa@m17n.org>
parents:
90206
diff
changeset
|
308 (cons (cons input output) |
26b71cf7f16d
(robin-define-package): Be sure to call put-char-code-property.
Kenichi Handa <handa@m17n.org>
parents:
90206
diff
changeset
|
309 pairs))) |
90124 | 310 ((not (stringp output)) |
311 (error "Bad output pattern %S" r)))) | |
312 (setcar (cdr new) docstring) ; replace "" above with real docstring | |
90204
7eec7b87433c
(robin-define-package): Make the expaneded form shorter.
Kenichi Handa <handa@m17n.org>
parents:
90126
diff
changeset
|
313 `(let ((slot (assoc ,name robin-package-alist)) |
90220
26b71cf7f16d
(robin-define-package): Be sure to call put-char-code-property.
Kenichi Handa <handa@m17n.org>
parents:
90206
diff
changeset
|
314 (newdef ',new) |
26b71cf7f16d
(robin-define-package): Be sure to call put-char-code-property.
Kenichi Handa <handa@m17n.org>
parents:
90206
diff
changeset
|
315 (prop ',iname) |
26b71cf7f16d
(robin-define-package): Be sure to call put-char-code-property.
Kenichi Handa <handa@m17n.org>
parents:
90206
diff
changeset
|
316 (lst ',pairs)) |
90204
7eec7b87433c
(robin-define-package): Make the expaneded form shorter.
Kenichi Handa <handa@m17n.org>
parents:
90126
diff
changeset
|
317 (if slot |
7eec7b87433c
(robin-define-package): Make the expaneded form shorter.
Kenichi Handa <handa@m17n.org>
parents:
90126
diff
changeset
|
318 (setcdr slot (cdr newdef)) |
7eec7b87433c
(robin-define-package): Make the expaneded form shorter.
Kenichi Handa <handa@m17n.org>
parents:
90126
diff
changeset
|
319 (setq robin-package-alist |
90220
26b71cf7f16d
(robin-define-package): Be sure to call put-char-code-property.
Kenichi Handa <handa@m17n.org>
parents:
90206
diff
changeset
|
320 (cons newdef robin-package-alist))) |
26b71cf7f16d
(robin-define-package): Be sure to call put-char-code-property.
Kenichi Handa <handa@m17n.org>
parents:
90206
diff
changeset
|
321 (dolist (l lst) |
26b71cf7f16d
(robin-define-package): Be sure to call put-char-code-property.
Kenichi Handa <handa@m17n.org>
parents:
90206
diff
changeset
|
322 (put-char-code-property (cdr l) prop (car l)))))) |
90124 | 323 |
324 ;;;###autoload | |
325 (defun robin-modify-package (name input output) | |
326 "Change a rule in an already defined robin package. | |
327 | |
328 NAME is the string specifying a robin package. | |
329 INPUT is a string that specifies the input pattern. | |
330 OUTPUT is either a character or a string to be generated." | |
331 | |
332 (let ((tree (assoc name robin-package-alist)) | |
333 docstring) | |
334 (if (not tree) | |
335 (error "No such robin package") | |
336 (setq docstring (cadr tree)) | |
337 (setcar (cdr tree) "") | |
338 (robin-add-rule name tree input output) | |
339 (setcar (cdr tree) docstring) | |
340 (if (characterp output) | |
341 (put-char-code-property output (intern name) input)))) | |
342 output) | |
343 | |
344 (defun robin-add-rule (name tree input output) | |
345 "Add translation rule (INPUT OUTPUT) to TREE whose name is NAME. | |
346 Internal use only." | |
347 | |
348 (let* ((head (aref input 0)) | |
349 (branch (assoc head tree)) | |
350 (sofar (cadr tree))) | |
351 | |
352 (if (= (length input) 1) | |
353 (if branch | |
354 | |
355 ;; A definition already exists for this input. | |
90206
4857b75944d3
(robin-define-package): Delete redundant
Kenichi Handa <handa@m17n.org>
parents:
90204
diff
changeset
|
356 ;; We do not cancel old char-code-property of OUTPUT |
4857b75944d3
(robin-define-package): Delete redundant
Kenichi Handa <handa@m17n.org>
parents:
90204
diff
changeset
|
357 ;; so that n-to-1 reverse conversion is possible. |
4857b75944d3
(robin-define-package): Delete redundant
Kenichi Handa <handa@m17n.org>
parents:
90204
diff
changeset
|
358 (setcar (cdr branch) output) |
90124 | 359 |
360 ;; New definition for this input. | |
361 (setcdr (last tree) (list (list head output)))) | |
362 | |
363 (unless branch | |
364 (if (characterp sofar) | |
365 (setq sofar (char-to-string sofar))) | |
366 (setq branch | |
367 (list head | |
368 (concat sofar | |
369 (char-to-string head)))) | |
370 (setcdr (last tree) (list branch))) | |
371 | |
372 (robin-add-rule name branch (substring input 1) output)))) | |
373 | |
374 ;;; Interactive use | |
375 | |
376 (defvar robin-mode nil | |
377 "If non-nil, `robin-input-method' is active.") | |
378 (make-variable-buffer-local 'robin-mode) | |
379 | |
380 (defvar robin-current-package-name nil | |
381 "String representing the name of the current robin package. | |
382 Nil means no packages is selected.") | |
383 (make-variable-buffer-local 'robin-current-package-name) | |
384 | |
385 ;;;###autoload | |
386 (defun robin-use-package (name) | |
387 "Start using robin package NAME, which is a string." | |
388 | |
389 (let ((package (assoc name robin-package-alist))) | |
390 (unless package | |
391 (error "No such robin package")) | |
392 (setq robin-current-package-name name) | |
393 (robin-activate))) | |
394 | |
395 (defun robin-inactivate () | |
396 "Inactivate robin input method." | |
397 | |
398 (interactive) | |
399 (robin-activate -1)) | |
400 | |
401 (defun robin-activate (&optional arg) | |
402 "Activate robin input method. | |
403 | |
404 With ARG, activate robin input method iff ARG is positive. | |
405 | |
406 While this input method is active, the variable | |
407 `input-method-function' is bound to the function `robin-input-method'." | |
408 (if (and arg | |
409 (< (prefix-numeric-value arg) 0)) | |
410 | |
411 ;; inactivate robin input method. | |
412 (unwind-protect | |
413 (progn | |
414 (setq robin-mode nil) | |
415 (setq describe-current-input-method-function nil) | |
416 (run-hooks 'robin-inactivate-hook)) | |
417 (kill-local-variable 'input-method-function)) | |
418 | |
419 ;; activate robin input method. | |
420 (setq robin-mode t | |
421 describe-current-input-method-function 'robin-help | |
422 inactivate-current-input-method-function 'robin-inactivate) | |
423 (if (eq (selected-window) (minibuffer-window)) | |
424 (add-hook 'minibuffer-exit-hook 'robin-exit-from-minibuffer)) | |
425 (run-hooks 'input-method-activate-hook | |
426 'robin-activate-hook) | |
427 (set (make-local-variable 'input-method-function) | |
428 'robin-input-method))) | |
429 | |
430 (defun robin-exit-from-minibuffer () | |
431 (inactivate-input-method) | |
432 (if (<= (minibuffer-depth) 1) | |
433 (remove-hook 'minibuffer-exit-hook 'robin-exit-from-minibuffer))) | |
434 | |
435 (defun robin-input-method (key) | |
436 "Interpret typed key sequence and insert into buffer." | |
437 | |
438 (if (or buffer-read-only | |
439 overriding-terminal-local-map | |
440 overriding-local-map) | |
441 (list key) | |
442 | |
443 (let ((echo-keystrokes 0) | |
444 (input-method-function nil) | |
445 (start (point)) | |
446 (tree (cddr (assoc robin-current-package-name robin-package-alist))) | |
447 branch | |
448 output) | |
449 | |
450 (while (setq branch (assq key tree)) | |
451 (delete-region start (point)) | |
452 (insert (setq output (cadr branch))) | |
453 (setq tree (cddr branch)) | |
454 (if tree | |
455 (setq key (read-event)) | |
456 (setq key nil))) | |
457 | |
458 (if (null output) | |
459 ;; body of the `while' above was not executed | |
460 (list key) | |
461 (delete-region start (point)) | |
462 (if key | |
463 (setq unread-command-events (list key))) | |
464 (if (stringp output) | |
465 (string-to-list output) | |
466 (list output)))))) | |
467 | |
468 (defun robin-help () | |
469 "Display the docstring of the current robin package." | |
470 | |
471 (interactive) | |
472 (let ((buf (get-buffer-create "*Robin Help*")) | |
473 (doc (cadr (assoc robin-current-package-name robin-package-alist)))) | |
474 (set-buffer buf) | |
475 (erase-buffer) | |
476 (insert doc) | |
477 (goto-char (point-min)) | |
478 (display-buffer buf))) | |
479 | |
480 ;;; Batch mode | |
481 | |
482 (defun robin-convert-buffer (&optional name) | |
483 "Convert the content of current buffer using a robin package. | |
484 NAME, if given, is a string specifying a robin package. If NAME | |
485 is not given or nil, the value of `robin-current-package-name' is | |
486 used." | |
487 | |
488 (interactive "*") | |
489 (robin-convert-region (point-min) (point-max) name)) | |
490 | |
491 (defun robin-convert-region (begin end &optional name) | |
492 "Convert the region using a robin package. | |
493 NAME, if given, is a string specifying a robin package. If NAME | |
494 is not given or nil, the value of `robin-current-package-name' is | |
495 used." | |
496 | |
497 (interactive "*r") | |
498 (or name | |
499 (setq name robin-current-package-name) | |
500 (error "No robin package specified")) | |
501 | |
502 (let ((tree (assoc name robin-package-alist))) | |
503 (unless tree | |
504 (error "No such robin package")) | |
505 | |
506 (save-excursion | |
507 (save-restriction | |
508 (narrow-to-region begin end) | |
509 (goto-char (point-min)) | |
510 (while (not (eobp)) | |
511 (robin-convert-region-internal tree)))))) | |
512 | |
513 (defun robin-convert-region-internal (tree) | |
514 "Apply a robin rule defined in TREE to the current point. | |
515 Use the longest match method to select a rule." | |
516 | |
517 (let ((begin (point)) | |
518 end branch) | |
519 (while (setq branch (assq (following-char) tree)) | |
520 (setq tree branch) | |
521 (forward-char 1)) | |
522 | |
523 (setq end (point)) | |
524 (if (= begin end) | |
525 ;; no matching rule found; leave it as it is | |
526 (forward-char 1) | |
527 ;; replace the string | |
528 (goto-char begin) | |
529 (insert (cadr tree)) | |
530 (delete-char (- end begin))))) | |
531 | |
532 ;; for backward compatibility | |
533 | |
534 (fset 'robin-transliterate-region 'robin-convert-region) | |
535 (fset 'robin-transliterate-buffer 'robin-convert-buffer) | |
536 | |
537 ;;; Reverse conversion | |
538 | |
539 (defun robin-invert-buffer (&optional name) | |
540 "Apply reverse conversion to the content of current buffer. | |
541 NAME, if given, is a string specifying a robin package. If NAME | |
542 is not given or nil, the value of `robin-current-package-name' is | |
543 used." | |
544 | |
545 (interactive "*") | |
546 (robin-invert-region (point-min) (point-max) name)) | |
547 | |
548 (defun robin-invert-region (begin end &optional name) | |
549 "Apply reverse conversion to the region. | |
550 NAME, if given, is a string specifying a robin package. If NAME | |
551 is not given or nil, the value of `robin-current-package-name' is | |
552 used." | |
553 | |
554 (interactive "*r") | |
555 (or name | |
556 (setq name robin-current-package-name) | |
557 (error "No robin package specified")) | |
558 | |
559 (setq name (intern name)) | |
560 (let (str) | |
561 (save-restriction | |
562 (narrow-to-region begin end) | |
563 (goto-char (point-min)) | |
564 (while (not (eobp)) | |
565 (if (not (setq str (get-char-code-property (following-char) name))) | |
566 (forward-char 1) | |
567 (insert str) | |
568 (delete-char 1)))))) | |
569 | |
570 (provide 'robin) | |
571 | |
572 ;;; Local Variables: | |
573 ;;; coding: utf-8-emacs | |
574 ;;; End: | |
575 | |
90126
8ee106ee2dc8
Changes from arch/CVS synchronization
Miles Bader <miles@gnu.org>
parents:
90124
diff
changeset
|
576 ;; arch-tag: ba995140-7436-4a57-b875-747fc340f605 |
90124 | 577 ;;; robin.el ends here |