Robin - Yet another input method

Japanese version is here.
French version is here.

We are the Robin. We will add your transliterational and traditional input methods to our own. Resistance is futile.

Download (2005-07-27, 35KB)

Table of Contents

Functionalities

Robin is a new input method for GNU Emacs. It has three functionalities.

  1. It serves as a simple input method. When the user types an ASCII key sequence, robin converts it into a string. This functionality is most likely used to input non-ASCII characters.
  2. It converts existing buffer substring into another string. This functionality is similar to the 1. above, but the input is buffer substring rather than key strokes.
  3. It offers reverse conversion. Each character produced by a robin rule can hold the original ASCII sequence as a char-code-property.

How to define conversion rules

Each conversion rule belongs to a robin package. A robin package is identified by a string called package name. Use robin-define-package to define a robin package.


(robin-define-package NAME DOCTSTRING
  (INPUT1 OUPUT1)
  (INPUT2 OUPUT2)
  ...)

NAME is a string identifying the robin package. It often starts with a language name and followed by a method name. For example, french-postfix, greek-prefix, etc.

DOCSTRING is a documentation string for this package.

INPUT* is an ASCII string that is to be transliterated.

OUTPUT* is a string or a character that is to be inserted as the result of transliteration.

Neither INPUT* nor OUTPUT* are evaluated. Do not use a variable or a function in those parts. Instead, use a string or character literal directly.

If multiple rules have the same input pattern but different output patterns, only the latest definition is effective.

Example


(robin-define-package "german-example"
 "An example for German

AE -> Ä   OE -> Ö   UE -> Ü
ae -> ä   oe -> ö   ue -> ü   ss -> ß

Repeat E or S to input itself.

AEE -> AE   OEE -> OE   UEE -> UE
aee -> ae   oee -> oe   uee -> ue   sss -> ss"

 ("AE" ?Ä)
 ("OE" ?Ö)
 ("UE" ?Ü)
 ("ae" ?ä)
 ("oe" ?ö)
 ("ue" ?ü)
 ("ss" ?ß)

 ("AEE" "AE")
 ("OEE" "OE")
 ("UEE" "UE")
 ("aee" "ae")
 ("oee" "oe")
 ("uee" "ue")
 ("sss" "ss")
)

Using robin as an input method

To use a defined robin package as an input method, register it with the register-input-method function. For example,


(register-input-methed
 "german-example"
 "german"
 'robin-use-package
 "de"
 "An example for German")

The first argument is the robin package name.

The second argument is the language environment for which this robin package is used.

Use the symbol robin-use-package as the third argument.

The fourth argument is the prompt that appears in modeline when this input method is active.

The fifth argument is a documentation string; it may or may not be identical to the one that you specified in robin-define-package.

You can activate the robin input method by typing
C-u C-\ german-example RET
Just like a quail package, only C-\ suffices for subsequent invocation.

Using robin as a buffer transliterator

To transliterate buffer substring, use the following functions.


(robin-transliterate-buffer &optional name)

Transliterate the current buffer using a robin package. NAME, if given, is a string specifying a robin package. If NAME is not given or nil, the most recently activated robin package is used.


(robin-transliterate-region begin end &optional name)

Transliterate BEGIN to END using a robin package. NAME, if given, is a string specifying a robin package. If NAME is not given or nil, the most recently activated robin package is used.

Reverse conversion

If the output pattern defined in a robin rule is a character, that character has a char-code-property whose key is the symbol representation of the robin package name and whose value is the input pattern of that character. For example, with the "german-example" definition above,
(get-char-code-property ?Ä 'german-example) => "AE"
etc.

If you do not want to assign a char-code-property to a character, use a string of length one as the output pattern, e.g.


(robin-define-package "german-example2"
 "Another example for German."

 ("AE" "Ä")
 ("OE" "Ö")
 ...)

Then
(get-char-code-property ?Ä 'german-example2) => nil
etc.

If multiple input patterns in a robin package generate the same character, the lastly used input pattern is given as the value of the char-code-property.

There are two functions for reverse conversion.


(robin-invert-buffer &optional name)

Apply reverse conversion to the content of current buffer. NAME, if given, is a string specifying a robin package. If NAME is not given or nil, the value of robin-current-package-name is used.


(robin-invert-region begin end &optional name)

Apply reverse conversion to the region. NAME, if given, is a string specifying a robin package. If NAME is not given or nil, the value of robin-current-package-name is used.

Modifying an existing rule

Use the robin-modify-package function to modify a rule already defined in a robin package.


(robin-modify-package name input output)

Change a rule in an already defined Robin package. NAME is the string specifying a robin package. INPUT is a string that specifies the input pattern. OUTPUT is either a character or a string to be generated.

The name of the game

As stated in Murphy's law, it took longer than expected to develop the very first version of Japanese input subsystem in NEmacs (Nihongo Emacs). So the subsystem was name "TAMAGO", which is an acronym of "TAkusan MAtasete GOmennasai" (Sorry to have kept you waiting so long). "Tamago" as a Japanese word means "egg", so the word "egg" was also used for related filenames and function names.

Since it was designed to input CJK characters, TAMAGO was rather big as a subsystem. So later in Mule (Multilingual Enhancement to GNU Emacs), we designed and implemented a smaller input subsystem. We had to give it a name. "So, what's smaller than an egg?" "A quail egg, of course." Therefore it was named "quail".

As time went by, quail became more and more complicated. That tendency was inevitable as long as we support CJK input. However, if we can limit ourselves to non-CJK characters, a much simpler transliteration mechanism suffices. So I wrote "robin", whose name was chosen because a robin is smaller than a quail. I could name it "hummingbird" or "nightingale", but those spellings seemed too long.


Last modified : 14 August 2006