Skip to content

Commit

Permalink
adds inline qmk_info
Browse files Browse the repository at this point in the history
  • Loading branch information
patricksurry committed Dec 8, 2023
1 parent 9018823 commit 176962c
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
19 changes: 17 additions & 2 deletions KEYMAP_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ This field provides information about the physical layout of the keyboard, i.e.,

1. **QMK `info.json` `layout` specification**:
This is the [official QMK format](https://docs.qmk.fm/#/reference_info_json?id=layout-format) for physical key descriptions
that every `info.json` file in the QMK firmware repository uses. `keymap-drawer` only uses the `x`, `y`, `r`, `rx` and `ry` fields.
that every `info.json` file in the QMK firmware repository uses.
`keymap-drawer` only uses the `x`, `y`, `w`, `h`, `r`, `rx` and `ry` fields.
The `x, y, w, h` specifies the key location and size (width, height) in `1u` units,
with `r` indicating the key rotation in degrees, centered at `rx, ry`.
Note that `keymap-editor` utilizes [the same format](https://github.com/nickcoutsos/keymap-editor/wiki/Defining-keyboard-layouts) for `info.json`.

QMK spec also lets you specify multiple "layouts" per keyboard corresponding to different layout macros to support physical variations.
Expand All @@ -37,10 +40,22 @@ This field provides information about the physical layout of the keyboard, i.e.,
visualize a given JSON definition, re-order keys using the "Re-order" tool and generate one from scratch from various formats such as KLE or Kicad
PCBs using the "Import" tool.

Alternatively you can write QMK layout inline with the `qmk_info` parameter
according to the official schema or a simple of key specs. For example:

```yaml
layout:
qmk_info: [
{x: 1, y: 0}, {x: 2, y: 0}, {x: 3, y: 0},
{x: 0, y: 1}, {x: 1, y: 1}, {x: 2, y: 1}, {x: 3, y: 1, h: 2},
...
]
```

Note that the behavior of the layout helper and `keymap-drawer` differs for rotated keys when omitting `rx`, `ry` parameters --
`keymap-drawer` assumes rotation around the key center and layout helper assumes rotation around the top left of the key.
For this reason it is recommended to explicitly specify `rx`, `ry` fields if `r` is specified. You might also want to omit the fields
besides `x`, `y`, `r`, `rx` and `ry` in your final JSON since they won't be used by `keymap-drawer`.
besides `x`, `y`, `w`, `h`, `r`, `rx` and `ry` in your final JSON since they won't be used by `keymap-drawer`.

2. **Parametrized ortholinear layouts**:
This lets you specify parameters to automatically generate a split or non-split ortholinear layout.
Expand Down
16 changes: 16 additions & 0 deletions examples/tidbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
layout:
qmk_info: [
{x: 1, y: 0}, {x: 2, y: 0}, {x: 3, y: 0},
{x: 0, y: 1}, {x: 1, y: 1}, {x: 2, y: 1}, {x: 3, y: 1, h: 2},
{x: 0, y: 2}, {x: 1, y: 2}, {x: 2, y: 2}, # ^^ double height
{x: 0, y: 3}, {x: 1, y: 3}, {x: 2, y: 3}, {x: 3, y: 3, h: 2},
{x: 0, y: 4, w: 2}, {x: 2, y: 4} # ^^ double height
]

layers:
default:
- [ Esc, '*', '-']
- ['7', '8', '9', '+']
- ['4', '5', '6']
- ['1', '2', '3', Enter]
- ['0', '.']
11 changes: 6 additions & 5 deletions keymap_drawer/physical_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,26 +162,27 @@ def __rmul__(self, other: int | float) -> "PhysicalLayout":
return PhysicalLayout(keys=[other * k for k in self.keys])


def layout_factory(
def layout_factory( # pylint: disable=too-many-arguments
config: DrawConfig,
qmk_keyboard: str | None = None,
qmk_info_json: Path | None = None,
qmk_info: dict | None = None,
qmk_layout: str | None = None,
ortho_layout: dict | None = None,
) -> PhysicalLayout:
"""Create and return a physical layout, as determined by the combination of arguments passed."""
if len([arg for arg in (qmk_keyboard, qmk_info_json, ortho_layout) if arg is not None]) != 1:
if len([arg for arg in (qmk_keyboard, qmk_info_json, qmk_info, ortho_layout) if arg is not None]) != 1:
raise ValueError(
'Please provide exactly one of "qmk_keyboard", "qmk_info_json" or "ortho_layout" specs for physical layout'
)

if qmk_keyboard or qmk_info_json:
if qmk_keyboard or qmk_info_json or qmk_info:
if qmk_keyboard:
qmk_info = _get_qmk_info(qmk_keyboard, config.use_local_cache)
else: # qmk_info_json
assert qmk_info_json is not None
elif qmk_info_json:
with open(qmk_info_json, "rb") as f:
qmk_info = json.load(f)
assert qmk_info is not None

if isinstance(qmk_info, list):
assert qmk_layout is None, "Cannot use qmk_layout with a list-format QMK spec"
Expand Down

0 comments on commit 176962c

Please sign in to comment.