Step 6: Stores, 'any', and 'index'
Stores, 'any', and 'index'
When we have many similar rules, as in the last example on the previous page, we can group them
together into one rule by using stores. A store is a set of characters that are grouped under a
single name. Stores are used in rules with the any
and index
statements. We create a store
with a store
statement:
store(vowels) "aeiou"
This creates a store called "vowels", which contains the five lowercase vowels. Note that we could also have written the content of the store using ANSI or Unicode character codes, in the same way as the output.
The any
statement is used to match a character from a specific store. For example, the following rule
will replace any vowel with a period, when used with the store above:
+ any(vowels) > "."
The any
statement can be used in the context or in the key part of a rule. It cannot be used in
the output.
The second statement that is used with stores is the index
statement. It is usually used in the output
of a rule, and will output the character from a particular store at the same position as the character
matched by a specified any
statement. This is best shown with an example; this rule will convert all
input to uppercase:
store(lowercase) "abcdefghijklmnopqrstuvwxyz" store(uppercase) "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + any(lowercase) > index(uppercase,1)
When a letter, such as "j" is typed, the any
statement finds its position in the "lowercase" store; the
index
statement then gets this index from the any
statement, and outputs the character at the same
position in the "uppercase" store, in this case "J".
The index
statement has two parts: the store from which it takes the output character, and the number
of the any
statement that it gets the character position from. This number is found by counting the
characters in the context and key parts of the rule up to the any statement. Again, a few examples may
help to illustrate this:
"a" + any(somestore) > index(otherstore,2) c The 'any' statement c is character #2 "ab" any(somestore) + "c" > index(otherstore,3) c The 'any' statement c is character #3 c Here the 'index' statement references the second 'any' statement used, c which is character #4 U+0041 any(somestore) "B" + any(otherstore) > index(thirdstore,4) c You can have multiple 'index' statements in the output, which can c reference the same or different 'any's any(store1) + any(store2) > index(store1,2) index(store2,1) index(store3,2)
Using stores in the Quick French keyboard
We can now reduce the number of rules needed for the Quick French keyboard by using stores. We will make
five stores: one for the unaccented vowels, and one each for vowels with acute accents, grave accents,
circumflexes, and diereses. For clarity, the group
statement is repeated below:
group(Main) using keys store( plainvowels ) 'a' 'e' 'i' 'o' 'u' 'A' 'E' 'I' 'O' 'U' store( acutevowels ) U+00E1 U+00E9 U+00ED U+00F3 U+00FA U+00C1 U+00C9 U+00CD U+00D3 U+00DA store( gravevowels ) U+00E0 U+00E8 U+00EC U+00F2 U+00F9 U+00C0 U+00C8 U+00CC U+00D2 U+00D9 store( circumvowels ) U+00E2 U+00EA U+00EE U+00F4 U+00FB U+00C2 U+00CA U+00CE U+00D4 U+00DB store( dresisvowels ) U+00E4 U+00EB U+00EF U+00F6 U+00FC U+00C4 U+00CB U+00CF U+00D6 U+00DC "'" + any( plainvowels ) > index( acutevowels, 2 ) "`" + any( plainvowels ) > index( gravevowels, 2 ) "^" + any( plainvowels ) > index( circumvowels, 2 ) '"' + any( plainvowels ) > index( dresisvowels, 2 )
This is far clearer than the long list of rules that we used earlier. Obviously we should add one or two more ordinary rules to produce upper- and lower-case 'ç', 'ý', and also the angled quotes '«' and '»'. Then we will have almost finished the keyboard:
"'" + "y" > U+00FD c Acute-accented Y "'" + "Y" > U+00DD "'" + "c" > U+00E7 c C-cedilla "'" + "C" > U+00C7 "<" + "<" > U+00AB c Angled quotes ">" + ">" > U+00BB
All we need to do now is to test the keyboard.