keymapviz icon indicating copy to clipboard operation
keymapviz copied to clipboard

[Suggestion] Leverage QMK's info.json for diagrams

Open precondition opened this issue 3 years ago • 0 comments

Currently, adding keymapviz support for a keyboard requires a considerable amount of manual effort; This is not scalable to QMK's 2k+ boards.

An "easy" way to extend keymapviz's support from 16 boards to ~2k keyboards would be to take inspiration from qmk info -m.

To give an example, qmk info --matrix --keyboard merge/um70 reads qmk_firmware/keyboards/merge/um70/info.json to determine how to draw the layout diagram (this is also what the online QMK configurator uses to draw the layout)

❯ qmk info -m -kb merge/um70
Keyboard Name: UM-70
Manufacturer: Merge
Website: https://mergedesign.store/um-70
Maintainer: duoshock
Keyboard Folder: merge/um70
Layouts: LAYOUT_lspace_2u_bksp, LAYOUT_lspace_split_bksp, LAYOUT_rspace_2u_bksp, LAYOUT_rspace_split_bksp
Processor: atmega32u4
Bootloader: atmel-dfu
Matrix for "LAYOUT_rspace_split_bksp":
      ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐  ┌──┐
      │0A││0B││0C││0D││0E││0F││0G│   │5A││5B││5C││5D││5E││5F││5G││5H│  │7H│
      └──┘└──┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└──┘└──┘  └──┘
      ┌────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌────┐  ┌──┐
      │1A  ││1B││1C││1D││1E││1F│   │6A││6B││6C││6D││6E││6F││6G││6H  │  │8H│
      └────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└──┘└────┘  └──┘
┌──┐  ┌─────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌───────┐  ┌──┐
│4F│  │2A   ││2B││2C││2D││2E││2F│   │7A││7B││7C││7D││7E││7F││7G     │  │9H│
└──┘  └─────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└───────┘  └──┘
┌──┐  ┌───────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌─────┐
│4G│  │3A     ││3B││3C││3D││3E││3F│   │8A││8B││8C││8D││8E││8F   │ ┌──┐
└──┘  └───────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└─────┘ │8G│
┌──┐  ┌───┐┌───┐┌───┐┌───┐┌───────┐   ┌─────────┐┌────┐┌────┐     └──┘
│4H│  │4A ││4B ││4C ││4D ││4E     │   │9A       ││9B  ││9C  │ ┌──┐┌──┐┌──┐
└──┘  └───┘└───┘└───┘└───┘└───────┘   └─────────┘└────┘└────┘ │9D││9E││9F│
                                                              └──┘└──┘└──┘
Matrix for "LAYOUT_rspace_2u_bksp":
      ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──────┐  ┌──┐
      │0A││0B││0C││0D││0E││0F││0G│   │5A││5B││5C││5D││5E││5F││5H    │  │7H│
      └──┘└──┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└──────┘  └──┘
      ┌────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌────┐  ┌──┐
      │1A  ││1B││1C││1D││1E││1F│   │6A││6B││6C││6D││6E││6F││6G││6H  │  │8H│
      └────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└──┘└────┘  └──┘
┌──┐  ┌─────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌───────┐  ┌──┐
│4F│  │2A   ││2B││2C││2D││2E││2F│   │7A││7B││7C││7D││7E││7F││7G     │  │9H│
└──┘  └─────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└───────┘  └──┘
┌──┐  ┌───────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌─────┐
│4G│  │3A     ││3B││3C││3D││3E││3F│   │8A││8B││8C││8D││8E││8F   │ ┌──┐
└──┘  └───────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└─────┘ │8G│
┌──┐  ┌───┐┌───┐┌───┐┌───┐┌───────┐   ┌─────────┐┌────┐┌────┐     └──┘
│4H│  │4A ││4B ││4C ││4D ││4E     │   │9A       ││9B  ││9C  │ ┌──┐┌──┐┌──┐
└──┘  └───┘└───┘└───┘└───┘└───────┘   └─────────┘└────┘└────┘ │9D││9E││9F│
                                                              └──┘└──┘└──┘
Matrix for "LAYOUT_lspace_2u_bksp":
      ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──────┐  ┌──┐
      │0A││0B││0C││0D││0E││0F││0G│   │5A││5B││5C││5D││5E││5F││5H    │  │7H│
      └──┘└──┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└──────┘  └──┘
      ┌────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌────┐  ┌──┐
      │1A  ││1B││1C││1D││1E││1F│   │6A││6B││6C││6D││6E││6F││6G││6H  │  │8H│
      └────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└──┘└────┘  └──┘
┌──┐  ┌─────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌───────┐  ┌──┐
│4F│  │2A   ││2B││2C││2D││2E││2F│   │7A││7B││7C││7D││7E││7F││7G     │  │9H│
└──┘  └─────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└───────┘  └──┘
┌──┐  ┌───────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌─────┐
│4G│  │3A     ││3B││3C││3D││3E││3F│   │8A││8B││8C││8D││8E││8F   │ ┌──┐
└──┘  └───────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└─────┘ │8G│
┌──┐  ┌───┐┌───┐┌───┐┌───────┐┌───┐   ┌─────────┐┌────┐┌────┐     └──┘
│4H│  │4A ││4B ││4C ││4E     ││4D │   │9A       ││9B  ││9C  │ ┌──┐┌──┐┌──┐
└──┘  └───┘└───┘└───┘└───────┘└───┘   └─────────┘└────┘└────┘ │9D││9E││9F│
                                                              └──┘└──┘└──┘
Matrix for "LAYOUT_lspace_split_bksp":
      ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐  ┌──┐
      │0A││0B││0C││0D││0E││0F││0G│   │5A││5B││5C││5D││5E││5F││5G││5H│  │7H│
      └──┘└──┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└──┘└──┘  └──┘
      ┌────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌────┐  ┌──┐
      │1A  ││1B││1C││1D││1E││1F│   │6A││6B││6C││6D││6E││6F││6G││6H  │  │8H│
      └────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└──┘└────┘  └──┘
┌──┐  ┌─────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌───────┐  ┌──┐
│4F│  │2A   ││2B││2C││2D││2E││2F│   │7A││7B││7C││7D││7E││7F││7G     │  │9H│
└──┘  └─────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└──┘└───────┘  └──┘
┌──┐  ┌───────┐┌──┐┌──┐┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌─────┐
│4G│  │3A     ││3B││3C││3D││3E││3F│   │8A││8B││8C││8D││8E││8F   │ ┌──┐
└──┘  └───────┘└──┘└──┘└──┘└──┘└──┘   └──┘└──┘└──┘└──┘└──┘└─────┘ │8G│
┌──┐  ┌───┐┌───┐┌───┐┌───────┐┌───┐   ┌─────────┐┌────┐┌────┐     └──┘
│4H│  │4A ││4B ││4C ││4E     ││4D │   │9A       ││9B  ││9C  │ ┌──┐┌──┐┌──┐
└──┘  └───┘└───┘└───┘└───────┘└───┘   └─────────┘└────┘└────┘ │9D││9E││9F│
                                                              └──┘└──┘└──┘

I'm not suggesting that we use the same display style for keymapviz as qmk info -m (having dedicated outlines for each key takes too much screen space and doesn't leave enough space for actual key legends) but we can write a program that reads layout x,y information and generates a keymapviz-style string template.

info.json and qmk info -f json are both viable methods but the latter would require calling the QMK CLI in a subprocess and check its output so my preference would go to simply reading the info.json file instead since we don't need any of the extra information that qmk info -f json provides.

~/qmk_firmware
❯ cat keyboards/binepad/bn003/info.json 
{
  "keyboard_name": "BN003",
  "url": "https://binepad.com",
  "maintainer": "binepad",
  "layouts": {
    "LAYOUT": {
      "layout": [
        {
          "label": "K0",
          "x": 0,
          "y": 0
        },
        {
          "label": "K1",
          "x": 1,
          "y": 0
        },
        {
          "label": "K2",
          "x": 2,
          "y": 0
        }
      ]
    }
  }
}

~/qmk_firmware
❯ qmk info --keyboard binepad/bn003 -f json | jq ".layouts"
{
  "LAYOUT": {
    "c_macro": true,
    "filename": "keyboards/binepad/bn003/bn003.h",
    "layout": [
      {
        "label": "K0",
        "matrix": [
          0,
          0
        ],
        "w": 1,
        "x": 0,
        "y": 0
      },
      {
        "label": "K1",
        "matrix": [
          0,
          1
        ],
        "w": 1,
        "x": 1,
        "y": 0
      },
      {
        "label": "K2",
        "matrix": [
          0,
          2
        ],
        "w": 1,
        "x": 2,
        "y": 0
      }
    ]
  }
}

One downside is that it is not possible (at least easily) to infer a good-looking KLE template from the layout diagram info but clearly the main usecase of keymapviz is to automatically generate ASCII visualisations in the keymap.c file so the absence of KLE support is not a deal-breaker. We can document the few keyboards that have had KLE support manually added in and let other keyboards graciously "fail" in case the user tries to generate a KLE JSON for an unsupported keyboard and leave a notice saying that "Option -t json is currently not supported for this keyboard.".

precondition avatar Feb 07 '22 14:02 precondition