Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added cdn/dev/img/developer/ldml/layers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1,136 changes: 1,136 additions & 0 deletions cdn/dev/img/developer/ldml/layers.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions developer/ldml/guide/displays.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
title: Customizing Keytop Displays
---

## Why customize the display

Normally, the display of a keytop, whether in a touch environment or the
on-screen display of a hardware keyboard, simply matches the characrer output.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
on-screen display of a hardware keyboard, simply matches the characrer output.
on-screen display of a hardware keyboard, simply matches the character output.

So, a key that outputs `a` will have a keytop that looks like `a`.

However, there are some situations where it is desirable to customize the
display of a key. This is where the [display] element is useful. This is an
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
display of a key. This is where the [display] element is useful. This is an
display of a key. This is where the [`display`] element is useful. This is an

optional element.

Some situations where you might want to customize the display are as follows.
This isn't an exhaustive list and there may be more situations where the display
feature is useful.

- Invisible characters: A key may output invisible text of some sort, such as a
space, control, or a keyboard [marker](./markers.md). Such keys can have a
customized keycap that displays something helpful for the users. For example,
`sp` for a space key.

- Switch keys: A key which switches layers, such as one that changes to a shift
or alternate layer.

- Visible characters with challenging display: doubled combining marks or
combining marks without a base character might need special handling, such as
choosing a different base character. A combining circumflex U+0302 could be
represented by a caret `^`.

## Example displays element

```xml
<displays>
<!-- show the key which outputs a no-break space as 'NBSP' -->
<display output="\u{00A0}" display="NBSP" />
<!-- show the marker 'grave' as a backquote -->
<display output="\m{grave}" display="`" />
<!-- show the key named 'switch-numbers' as '123' -->
<display keyId="switch-numbers" display="123" />
</displays>
```

## displayOptions

The `displayOptions` has a single configurable option at present, the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The `displayOptions` has a single configurable option at present, the
The [`displayOptions`] element has a single configurable option at present, the

baseCharacter.

In Lao for example, it's sometimes preferred to use `x` as the base for showing
combining marks, rather than the dotted circle ◌.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
combining marks, rather than the dotted circle .
combining marks, rather than the dotted circle `` (U+25CC).


This is a hint for platforms to suggest using an alternative character. It
doesn't require any specific behavior.

```xml
<displays>
<!-- other 'display' elements-->
<displayOptions baseCharacter="x"/>
</displays>
```


With the key display customized, it's time now to arrange the keys into
[layers](./layers).

[display]: ../reference/display
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[display]: ../reference/display
[`display`]: ../reference/display
[`displayOptions`]: ../reference/displayOptions

My pref would be to show all elements in code format. There are quite a few instances I have missed, I think!

13 changes: 9 additions & 4 deletions developer/ldml/guide/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@ title: Glossary for LDML

### BCP 47 language tag

A standardized code that is used to identify human languages on the Internet. More on [BCP 47](https://www.rfc-editor.org/info/bcp47).
A standardized code that is used to identify human languages on the Internet.
More on [BCP 47](https://www.rfc-editor.org/info/bcp47).

There are many possible subtags, but only three types are currently used in most places in Keyman Developer:
There are many possible subtags, but only three types are currently used in most
places in Keyman Developer:

* [language subtag](../../current-version/reference/bcp-47#toc-the-language-subtag)
* [language
subtag](../../current-version/reference/bcp-47#toc-the-language-subtag)
* [script subtag](../../current-version/reference/bcp-47#toc-the-script-subtag)
* [region subtag](../../current-version/reference/bcp-47#toc-the-region-subtag)

More information about BCP 47 language tag and full details on [how they are used in Keyman Developer](../../current-version/reference/bcp-47).
More information about BCP 47 language tag and full details on [how they are
used in Keyman Developer](../../current-version/reference/bcp-47).

Now, go on to begin [planning](./planning) your LDML keyboard.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The glossary should be expanded to include as many of the technical terms used in LDML as possible e.g. Keybag, Displays, Layers, shift layer, Variables, Transforms, Markers, Reorders, Elements, base physical types (US, ISO), organisation of keys (QWERTY, AZERTY, QWERTZ), touch-only keyboard, gestures, long press, flick, multitap, LDML, XML, locale, (element) attribute, DTD, CLDR, repertoire, key element, keys element, (key) gap, (key) stretch, keytop, keycap, switch key, layer group, modifier, (keyboard) row, etc.
Some of these terms you could just give a short entry and a link to either an internal or external definition/description (e.g. the key element is described in keybag.md).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that this para makes sense now that the Glossary is the final page in the Guide section. I would remove it or replace it with 'return to index'?

Suggested change
Now, go on to begin [planning](./planning) your LDML keyboard.
You have reached the end of the LDML keyboard authoring guide. Return to the [index](index).

27 changes: 25 additions & 2 deletions developer/ldml/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,30 @@
title: LDML Guide
---

## Language elements
This guide will take you through the concepts, planning process, and structure
needed to successfully author an LDML Keyboard used with Keyman.

* [LDML Language Overview](overview)
We recommend to start with [Planning](./planning) and read these pags in order,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
We recommend to start with [Planning](./planning) and read these pags in order,
We recommend that you start with [Planning](./planning) and read these pages in order,

but you are welcome to skip around as suits your interest. The
[reference](../reference/) is useful for details of a particular XML Element.

## Getting Started

* [Planning](planning) your Keyboard
* [Overview](overview) of the LDML format
* [Choosing a Locale](locales)

## Jumping in

* The [Keybag](keybag)
* Customizing key [Displays](displays)
* Defining [Layers](layers)

## Going further

* [Settings and Options](settings)
* [Variables](variables)
* [Transforms](transforms)
* [Markers](markers)
* [Reorders](reorders)
* [Glossary](glossary)
123 changes: 123 additions & 0 deletions developer/ldml/guide/keybag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
title: The Keybag
---

The first major part of authoring your keyboard consists in setting up the
keybag.

## What's in the Keybag?

You can think of the keybag as if it were a literal "bag of keys" from which you
can bring out a key and place it into the right spot in your layout.

The keybag is not one-for-one with the [repertoire], due to the following
reasons:
Comment on lines +13 to +14
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The keybag is not one-for-one with the [repertoire], due to the following
reasons:
The keybag is not one-for-one with the [repertoire], due to the following
reasons:


- There may be text which is of the repertoire which are not typed by the user
directly at all, but are accessed via transforms. For example, suppose `œ` were
part of the repertoire, but accessed by the user by typing `o` + `e`. There
might not be an `œ` key, though it is in the repertoire.
Comment on lines +16 to +19
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- There may be text which is of the repertoire which are not typed by the user
directly at all, but are accessed via transforms. For example, suppose `œ` were
part of the repertoire, but accessed by the user by typing `o` + `e`. There
might not be an `œ` key, though it is in the repertoire.
- There may be text which is of the repertoire which are not typed by the user
directly at all, but are accessed via transforms. For example, suppose `œ` were
part of the repertoire, but accessed by the user by typing `o` + `e`. There
might not be an `œ` key, though it is in the repertoire.


- There may also be more than one key which produces the same output, but has a
distinct identity as a key. For example, there might be a key producing `a`
which is used on a hardware layer, but also another key also producing `a` on
one of the touch layers which has gestures attached to it such as a long press
yielding `à`, `á`, `â` etc. The two `a` keys have diferent identities (`id=`
attribute) and differ in other properties.

- Rarer, but it may be possible that a key producing the same output
intentionally has a different keycap display in two different contexts. Keys
are identified by a unique identifier, so unique keys can have unique key
[displays].

## Defining keys in the Keybag

Keys are defined by the [key] element within the [keys] element, as seen in a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Keys are defined by the [key] element within the [keys] element, as seen in a
Keys are defined by the [`key`] element within the [`keys`] element, as seen in a

simple example:

```xml
<keys>
<key id="A" output="A" />
<key id="B" output="B" />
<key id="uppercase-c" output="C" />
<key id="lambda" output="λ" />
<key id="" output="" />
</keys>
```

Note that the identifier doesn't have to be plain ASCII, as shown in the last
key above, which has the ID of ``.

In the following sections we will discuss more advanced uses of keys.

## Switch Keys

A key within a touch layout can switch to a different [layer](./layers) by use
of the `layerId` attribute, which names another layer. For example, this key
switches to the "numbers" layer:

```xml
<key id="switch-numbers" layerId="numbers" />
```

Such a key would by default have a blank keycap (because it doesn't produce any
output), so it is recommended to use a [`display`](./displays) element to give
it an identifiable appearance. See the
[displays](./displays#example-displays-element) section for an example.
Comment on lines +63 to +66
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first of these should probably link to ../display rather ./displays?

Suggested change
Such a key would by default have a blank keycap (because it doesn't produce any
output), so it is recommended to use a [`display`](./displays) element to give
it an identifiable appearance. See the
[displays](./displays#example-displays-element) section for an example.
Such a key would by default have a blank keycap (because it doesn't produce any
output), so it is recommended to use a [`display`](../display) element to give
it an identifiable appearance. See the
[displays](./displays#example-displays-element) section for an example.


## Key Geometry

### Width

In a touch keyboard, keys are normally the same width (width="1" or
width="1.0"). In some cases, a key is given a larger width for layout reasons,
Comment on lines +72 to +73
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In a touch keyboard, keys are normally the same width (width="1" or
width="1.0"). In some cases, a key is given a larger width for layout reasons,
In a touch keyboard, keys are normally the same width (`width="1"` or
`width="1.0"`). In some cases, a key is given a larger width for layout reasons,

such as for the shift key. Widths are in tenths of a key width.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Widths are in tenths of a key width.

I am not sure what this means? Do you mean that you can define fractional widths to 1 decimal place? (That may not be adequate; we often see keyboards with much finer width spes in Keyman)


```xml
<key id="wideshift" width="3" toLayer="uppercase" />
```

### Gap

Sometimes on a key layout, it can be useful to have a blank area without any
keys. For example, a shifted layer may not have a shifted key defined for each
base key. The `gap="true"` attribute indicates that a key is a gap and has no
output and no key cap display.

There is a pre-defined key named `gap` that has the gap attribute set. It is
possible to add additional gap keys if desired. The following defines `gap` as
its normal definition, and then defines a 3-key wide gap.

```xml
<key id="gap" gap="true" /> <!-- gap=true is implied, but we can define it explicitly.-->
<key id="widegap" gap="true" width="3" />
```

### Stretch

The stretch attribute defines a key that expands to fill all available
horizontal space. This is used, for example, with the spacebar.
Comment on lines +98 to +99
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The stretch attribute defines a key that expands to fill all available
horizontal space. This is used, for example, with the spacebar.
The stretch attribute defines a key that expands to fill all available
horizontal space. This is used, for example, with the spacebar. There
can only be 1 stretch key on a given row.

Is my addition true?


```xml
<key id="space" output=" " stretch="true" />
```

## Marker key

Markers are discussed in more detail in [markers](./markers) and
[transforms](./transforms). For this discussion, it's used with a key that
doesn't generate any actual output, but represents an invisible non-text data
item that is used for later processing.

```xml
<key id="accent-grave" output="\m{grave}" />
```

The marker's id here is `grave`.

Next, we will learn about customizing key [displays].

[repertoire]: ./planning#repertoire
[displays]: ./displays
[keys]: ../reference/keys
[key]: ../reference/key
Comment on lines +122 to +123
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[keys]: ../reference/keys
[key]: ../reference/key
[`keys`]: ../reference/keys
[`key`]: ../reference/key

79 changes: 79 additions & 0 deletions developer/ldml/guide/layers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
title: Defining Layers
---

A layer defines are how keys are arranged for display and use.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A layer defines are how keys are arranged for display and use.
A layer defines how keys are arranged for display and use.

For hardware layouts, a layer determines which hardware key connects to which key from the keybag.
For touch layouts, the layer controls how the keys are displayed on the screen for interaction with the finger or mouse.

## Layer Groups (`layers`)

A layer group or [`layers`](../reference/layers) element occurs one or more times in the keyboard file.
There may be at most one layer group for the hardware keyboard, and then one or more layer group for different widths (sizes) of touch layouts, such as for a phone versus a tablet.

If no touch layer group is present, then the hardware layout will be used in touch devices, but a touch layout cannot be used for hardware, so we recommend starting with a hardware layout.

### Hardware Layer Groups

The hardware layer group has a `formId=` attribute referencing the physical layout of the keys, such as `iso` or `us` for the European 102 key layout (with a key between the shift and Z key) and the US 101 key layout (with no key between the shift and Z) respectively. Other layouts supported include `abnt2`, `jis`, and `ks`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, on French AZERTY and German QWERTZ, the Z key is not next to the shift key.

Do we want to use <kbd>Shift</kbd> for references to keys throughout? We'd have to be careful as to which places we apply that styling.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The hardware layer group has a `formId=` attribute referencing the physical layout of the keys, such as `iso` or `us` for the European 102 key layout (with a key between the shift and Z key) and the US 101 key layout (with no key between the shift and Z) respectively. Other layouts supported include `abnt2`, `jis`, and `ks`.
The hardware layer group has a `formId=` attribute referencing the physical layout of the keys, such as `iso` or `us` for the European 102 key layout (with a key between the shift and Z key) and the US 101 key layout (with no key between the shift and Z) respectively. Other layouts supported include `abnt2` (Brazil), `jis` (Japan), and `ks` (Korea).


### Touch Layer Groups

Touch layer groups always have the attribute `formId="touch"`, and are distinguished from each other by the `minDeviceWidth=` attribute, which specifies a minimum width, in millimeters, that the layout group must have.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Touch layer groups always have the attribute `formId="touch"`, and are distinguished from each other by the `minDeviceWidth=` attribute, which specifies a minimum width, in millimeters, that the layout group must have.
Touch layer groups always have the attribute `formId="touch"`, and are distinguished from each other by the `minDeviceWidth=` attribute, which specifies a minimum screen (or keyboard) width, in millimeters, that the device should have in order to use that layout group.


## Defining a Layer

Now we come to discuss the actual [`layer`](../reference/layer) element.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some of the other topics, you used a link footnote. Do you want to do the same here?

Suggested change
Now we come to discuss the actual [`layer`](../reference/layer) element.
Now we come to discuss the actual [`layer`] element.

And add at the bottom of the doc:

[`layer`]: ../reference/layer


### Layer ID

The ID is required for touch layers, but is optional for hardware layers. The layer with the ID of `base` is the starting layer.

Keys can switch layers by referencing this layer in their `layerId` attribute.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Keys can switch layers by referencing this layer in their `layerId` attribute.
Keys can be used to switch layers by referencing this layer in their `layerId` attribute.


### Modifiers

The modifiers are required for hardware layers, but are optional for touch layers.

Each layer has a set of modifiers defined. For hardware keyboards, this specifies which layer will be selected based on the modifiers held down. `none` is used for the layer with no modifiers.

For example, `modifiers="none"` or `modifiers="shift"`. See [`layer`](../reference/layer) for further details.

### Rows

Each layer contains one or more [`row`](../reference/row) elements, in order from top to bottom.

For example, most hardware keyboards have five rows including the space bar.
Note that for hardware layouts, only the "alphanumeric" keys, that is, the keys which produce a character or space, are included. Shift, Control, and any other device-specific hardware keys are not included.

For touch keyboards, the number of rows is completely up to the keyboard author. Different layers or layer groups do not have to have the same number of rows.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For touch keyboards, the number of rows is completely up to the keyboard author. Different layers or layer groups do not have to have the same number of rows.
For touch keyboards, the number of rows is completely up to the keyboard author. Different layers or layer groups do not have to have the same number of rows. However, for usability, it is recommended that the number of rows in touch layers is consistent within a single layer group.


The `keys` attribute of each `row` is a space-separated list of key IDs.

Example:

```xml
<layer modifiers="none">
<row keys="c-tikka 1 2 3 4 5 6 7 8 9 0 hyphen equal" />
<row keys="q w e r t y u i o p g-tikka h-maqtugha" />
<row keys="a s d f g h j k l semi-colon hash" />
<row keys="z-tikka z x c v b n m comma period slash" />
<row keys="space" />
</layer>
```

## Overview of Layers and Layer Groups

Here is a reference image to help you understand layers and layer groups.

![Image showing three layer groups. First, a layer group for hardware, with a
base and shifted layer. Then, a layer group for touch or mobile devices, that
is less than (in this example) 100 millimeters wide, having a "123" key to
switch to numbers. Finally, a layer group for wider or tablet devices, that is a
width of 100 or greater millimeters, having a separate number row above the
keyboard.](/cdn/dev/img/developer/ldml/layers.png)

-----

You've now completed a brief tour of the LDML format for Keyman. See [going
further](./index#toc-going-further) for additional topics to explore.
Comment on lines +78 to +79
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this point to settings now?

20 changes: 20 additions & 0 deletions developer/ldml/guide/locales.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Choosing a locale
---

As part of your keyboard development, you must choose one or more [BCP 47]
locale codes to associate with the keyboard.

The primary locale id is stored in the `locale` attribute of the
[`keyboard3`][keyboard3] (outer) element, while any additional locale ids are
stored in the optional [`locales`][locales] element.

Examples:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these examples be proper XML keyboard3 / locales elements?


- `km` — Khmer
- `suz-Sunu` — Sunuwar language, in the Sunuwar script
- `fa-t-k0-isiri` — Persian ISIRI keyboard
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little tricky because we don't currently support this format in Keyman, do we?


[BCP 47]: ../../current-version/reference/bcp-47
[keyboard3]: ../reference/keyboard3
[locales]: ../reference/locales
4 changes: 4 additions & 0 deletions developer/ldml/guide/markers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: Markers
---

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No content yet?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still in progress

Loading