Migrating to platform() from Compile Targets

Greetings All,

I’m making updates to migrate away from Compile Targets and to the platform() function, but I’m uncertain of the mappings from one to another. The equivalent for the KeymanWeb target seems obvious, its the Keyman Engine target that I’m less certain about. Can someone confirm or correct the following for me please? TIA!

Line Prefix: $keymanonly:
Target: Keyman Engine
Description: Covers both Windows and macOS versions of Keyman
Equivalent: platform( ‘windows macos’ )

Line Prefix: $keymanweb:
Target: KeymanWeb
Description: Covers any JavaScript keyboard, including touch layouts
Equivalent: platform( ‘web’ )


Great question. There actually isn’t a perfect one-to-one correspondence between platform() and compile targets. This is because they function quite differently:

  • Compile Targets determine which lines the compiler reads and which it ignores when preparing the output file. They can be used in any source line.
  • platform() statements are processed by the Keyman app, and are present in both .kmx and .js compiled files. platform() statements can be used only in rule lines (and not in match or nomatch). One of the current limitations of the platform() statement is that it is not an “or”. So platform('windows macos') would match nothing – there is not platform is that is both Windows and macOS. In Keyman 10, you’d need to repeat the rule to match both, or use platform('desktop').

Despite the caveats above on the platform() statement, I recommend using it because it more closely fits the needs of most platform differences in keyboards. The more general you can be, the better: so use platform('touch') as opposed to platform('ios'). The ability to mix and match components of the platform is also helpful, so platform('touch native') matches Keyman for Android and Keyman for iOS, but not KeymanWeb (in a browser such as Safari or Chrome on those platforms), whereas platform('touch web') would match only in a browser on a touch-aware mobile platform (currently KMW does not support touch fully on Windows).

$keymanonly: covers Windows and macOS. The best equivalent is platform('desktop native'). This would also match on Linux (in Keyman 11).

$keymanweb: would cover any JavaScript keyboard. However, platform('web') would only match when Keyman is running in KeymanWeb, not when running in Keyman for Android or Keyman for iOS. So they are not quite equivalent.

Hope this helps!

@Marc, thanks for the explanations, I understand the usage much better. Regarding an “or” for platform, perhaps use “,” in the argument since " " is an implicit “and”.

The logic I’m wanting to express with platform() would test for “JavaScript keyboard” or “NOT JavaScript keyboard”. Its not clear to me what platform values will use JavaScript. I guess it is “web” and “touch” that cover all JavaScript cases?

With out an “or”, “and” or “else”, might lead to:

platform(“web”) …do something…
platform(“touch”) …do the same thing…
if(&platform != “web”) if(&platform != “touch”) …do something else…

Provided one if() can follow another to express an “and”. I’m probably doing it the hard way, is there a simpler approach to get to : if ( …javascript… ) … else … ?

Support for “or”, “and”, “else” and scopes for “if” (like { }s or an endif) would be requests for the keyman language roadmap.

Can you elaborate on what the need is to differentiate on JavaScript vs not JavaScript? I’d like to understand your use-case better. It may be that compile targets are the best solution if you do need to differentiate on that basis.

Thanks for the response. Very specifically, I’d like to replace the following lines in the gff_amh_7.kmn file with platform conditionals:

$keymanonly: store(gIz-key) ‘eEäÄéÉèÈêÊëË’
$keymanweb: store(gIz-key) ‘eE’

I understood the lines to be copying different data into the gIz-key store depending on the target being JavaScript based or not. I expect now I’ve made the incorrect interpretation.


That looks to me like part of mnemonic layout support - giving those base keys on European layouts sensible behaviours. And as KMW does not yet fully support mnemonic layouts, the additional accented keys would have no effect.

Mnemonic layouts are one feature where cross-platform is not yet at feature parity - that is, only Windows native Keyman layouts really support them.

Mnemonic layout support is slightly improved in recent builds of KMW (but not yet fully supported). It would be worth testing to see if the Windows ($keymanonly) behaviour is a problem for web now; it may be that the KMW target is currently positional whereas the Windows target is mnemonic? You may find you can use the same source lines for both Windows and web and not need to make the distinction any longer.