Need help with Help Documentation

I’m having trouble understanding the reasoning/logic of the syntax/usage of the ‘any’ and ‘index’ features in relation to using Stores as presented in the Examples section. I think that some additional clarification or explanation would be helpful.

Reference page

The use of “1” after the ‘store’ referenced by ‘index’ is where I get confused/lost:

+ any(lowercase) > index(uppercase, 1)    c translate vowels to upper case

Why is this needed in this instance? What is its purpose? And what would be the result of changing the “1” to a “3” or other number?
The preceding text leads me to think that this example would transform any lowercase vowel to the first uppercase vowel in the store; and if the “1” were a “3” then any lowercase vowel would be transformed into the third uppercase vowel in the store.
So, how and why does “1” change any lowercase vowel to the uppercase vowel with the same corresponding index?
The logic I am familiar with from other languages would assume that NO specified index number refers to the corresponding (same) index number, and that specifying a number changes “any” of the first store’s contents into the item stored at that index number of the second named store. I think this is very sound and reasonable logic and that any deviation from this pattern deserves an explanation!

I would propose an Edit to the page myself, but I can’t make sense of it!

Thank you in advance to whomever renders me some assistance! I will be very grateful!

As I read further in the guide I ran into another example that confused me even more!

if(opt_composed = '0') any(vowel) + '^' > index(vowel, 2) U+0302
if(opt_composed = '1') any(vowel) + '^' > index(vowel_circum, 2)

Why the “2”? It seems clear that we’re not selecting the index item #2 from the store… and while there are two characters in the first example output, the vowel must come before the combining diacritic; and the second example has only one character output. What the heck does the “2” indicate?|

What the second number in the index refers to is the position of the store being matched on the left side of the wedge. So here it says index(uppercase, 1) because the lowercase is the first term after the wedge.

Now this seems pointless when there is only one term before the wedge, but imagine there were two:
any(lowercase) + any(consonant) > index(uppercase, 2) index(uppercons, 1)

This says the lower case vowel followed by a consonant needs to change to the corresponding uppercase vowel then upper case consonant. (Maybe not a very realistic example). But in this case the numbers in the index command point which store in the matching side to take the index number from. The first index comes from the first “any” the second index comes from the second “any”.

For the second example, there is only one “any” on the match side, but there are two references to stores, “opt_composed” and “vowel”. So the two means to look at the second store referenced.

OK, thank you very much for your excellent and thorough explanation!

I definitely think that the documentation should be much more clear and specific about that!

I feel that the second example I cited is especially strange. While it is a store, it is really a setting and will never appear as part of the context. Perhaps it would have made more sense if the syntax had been designed differently but this does not seem like something that can really be changed without breaking the keyboards that use this feature!

Again, I very much appreciate you explaining this in such a concise way!

To clarify slightly, the second parameter in the index statement is the corresponding element offset in the left hand side of the rule. This parameter is consistent with the context(n) statement, which has the same offset parameter, and which just emits the resulting character found at that offset in the context.

An element here is a single Unicode codepoint or a single statement. (Note that for historical reasons, the outs() statement is treated as multiple elements, one for each character in the referenced store. Yes, this makes me sad!)

We do welcome edits to documentation to improve clarity :slight_smile:

To follow up on Marc’s suggestion (and he’ll correct me if I get this wrong!):

Note: “you” refers to anyone reading this, not just the author of the original question!

Anyone can directly offer suggestions. To get set up to do this:

  • You need to have a GitHub account. If you don’t, go to and click “Sign up”.
  • You need to make a working copy of the Keyman help repository (called a “fork” in GitHub jargon). This working copy is stored on GitHub. You can make this “fork” by going to and clicking on the “Fork” button at the top right of the page.

Then, for example, you could

  • go to the page referenced above:
  • click on the blue “Edit page” tab at the lower right
  • edit the text in the page that opens
  • optionally add additional description or comments in the field at the bottom of the page
  • click on “Propose changes”

Then someone from the Keyman team will review your changes and, once approved, incorporate them into the documentation.

In that way, others will benefit from the work you did figuring out what was not clear!

:see_no_evil: All looks correct, just one small ‘simplification’?

GitHub prompts you to fork the repository when you click on “Propose Changes” :slight_smile: . GitHub also asks you to sign up when you click the Edit link, if you don’t already have an account.