Skip to content

Releases: caksoylar/keymap-drawer

v0.19.0

23 Nov 01:25
Compare
Choose a tag to compare

This release updates ZMK parsing to use a tree-sitter-based parser and adds support for ZMK physical layouts in devicetree format (used by Studio), among other improvements.

The new parsing implementation results in speed improvements that range from 10% shorter runtime to 7x, with a median speed-up of ~2x in my test cases.
If you encounter any new problems with parsing your keymaps, please open an issue!

Features

Drawing

  • Add dts_layout option for physical layouts, and corresponding --dts-layout CLI arg.
    • This is analogous to qmk_info_json field pointing to a file path, except the file should contain ZMK's physical layout nodes in devicetree
  • Deprecated qmk_layout field in physical layout definitions, and corresponding--qmk-layout CLI arg.
    Use layout_name instead, which also works with dts_layout above

Parsing

  • Add parse_config.layer_legend_map which can be used to customize how layer names are represented in the keymap
    • This is similar to how e.g. zmk_keycode_map is used to change keycode representations, but applied to layer names instead
  • Switch to a tree-sitter-devicetree-based parser for ZMK, from the old pyparsing-based one
  • Add --virtual-layers CLI argument to keymap parse
    • This appends empty "virtual" layers at the end of the keymap; this can be used for assigning combos etc. to show them on a separate diagram
  • Also look-up behavior prefixes in raw_binding_map
    • For example match entries like &td for ZMK behavior bindings like &td 0 to fix for behaviors nested in hold-taps

Fixes

  • Ignore "reserved" ZMK layers while parsing, used for ZMK Studio
    • Better support for Studio-related ZMK updates to come, see #125
  • Switch to using Github raw URL for mdi glyphs, by @magicDGS in #132
    • The old unpkg URL was unreliable and seems to have eventually disappeared
  • Add retries and a more generous timeout for fetching SVG glyphs from remote URLs
  • More correctly center/normalize QMK physical layouts when there are rotated keys

ZMK drawing workflow

New Contributors

Full Changelog: v0.18.1...v0.19.0

v0.18.1

09 Oct 20:42
Compare
Choose a tag to compare

This release contains a couple bug fixes.

  • Avoid newlines between 2 tspan elements by @wouterj in #114. This fixes the annoying horizontal mis-alignment when the tap legend had 3+lines.
  • Add an additional u alias for key width in json-format qmk_keyboard. This is sometimes emitted by https://nickcoutsos.github.io/keymap-layout-tools after importing e.g. Kicad PCB files.

v0.18.0: ZMK modules support and layer key styling

04 Aug 22:15
Compare
Choose a tag to compare

This release adds support for parsing ZMK configs that use modules like zmk-helpers with additional config options, along with adding special styling to layer key legends and making them clickable.

Edit: zmk-helpers now have docs on using keymap-drawer with it using below changes.

Features

Drawing

  • Breaking change: Add new config option draw_config.style_layer_activators which defaults to true. This marks layer activators legends by adding a link that goes to the corresponding layer (might not work for embedded SVGs), and adding an underline by default.

    • If you want to restore the old behavior, this setting can be disabled in the config file: draw_config: { style_layer_activators: false }
    • You can change the styling, e.g. if you want italic instead of underlined:
      draw_config:
        svg_extra_style: |
          text.layer-activator { text-decoration: none; font-style: italic }
  • Add a new CSS class alternate so you can define separate styling for extra activators marked by the parse_config.mark_alternate_layer_activators config (no styling defined by default) (#98)

    • Example:
      parse_config:
        mark_alternate_layer_activators: true
      draw_config:
        svg_extra_style: |
          rect.held.alternate { fill: #478583; }
          @media (prefers-color-scheme: dark) { rect.held.alternate { fill: #478583; } }  # some other color here
  • Add hidden property to the combo spec, so you can avoid drawing certain combos that the parser outputs by adding hidden: true (for instance through parse_config.zmk_combos) (#104)

    • Example:
      parse_config:
        zmk_combos: 
          combo_esc: { hidden: true }
  • Support using underscore instead of space as split separator for the cols+thumbs notation spec in order to reduce command line quoting issues

    • Example: keymap draw -n 33333+2_3+233331 my_asymmetric_keymap.yaml
  • Implement support for layout_aliases in qmk_keyboard physical layout definitions

Parsing

  • Add parse_config.zmk_additional_includes to augment the preprocessor include path (#105)
    • This can be used to be able to parse keymaps using zmk-helpers using the module functionality, since #includes aren't using relative paths in that case. Example:
      parse_config:
        zmk_additional_includes: [ "zmk-helpers/include" ]
    • If you want to use it in the automated ZMK drawing workflow, use the new west_config_path argument to the workflow (#107) so that the modules defined in the west.yml file are automatically fetched. (You still need the above value in the config.) Example:
      jobs:
        draw:
          uses: caksoylar/keymap-drawer/.github/workflows/draw-zmk.yml@main
          permissions:
            contents: write  # allow workflow to commit to the repo
          with:
            [...]
            west_config_path: 'config'  # this folder contains west.yml with module definitions
    • Module fetching is not (yet) supported in the ZMK URL parse option of the web app
  • Add parse_config.zmk_preamble config option which is text inserted at the beginning of the keymap, usually used to modify preprocessor behavior. It defaults to #define KEYMAP_DRAWER (#103)
    • The default value exposes the existing behavior which was being defined internally before this change
  • Restore support for using modified keycodes like LC(LEFT) in parse_config.*_keycode_map that was removed in v0.16 (#106)

Fixes

  • More robust devicetree parsing because of a few fixes involving parsing phandle arrays, such as when elements can have commas or split to multiple <...>, <...>; blocks (#102)
  • More robust QMK keymap.json parsing, for cases where the keycodes can contain extra spaces

Misc

  • Add a physical layout definition for hummingbird keyboard
  • For unibody keyboards like fingerpunch/ffkb and rufous, change the default physical layout to avoid all keys being rotated. This should improve readability by sacrificing faithfulness to the actual layout
    • The older rotated versions are available using fingerpunch/ffkb_rotated and rufous_rotated

Full Changelog: v0.17.0...v0.18.0

v0.17.0

27 May 05:17
Compare
Choose a tag to compare

This is a release with minor external-facing changes, since most of them were internal tweaks to help downstream users like the web app.
I recently spent some time working on it at https://caksoylar.github.io/keymap-drawer and implemented a few improvements (and added sorely needed tooltips). If you haven't checked it out lately, you might want to have a look!

Also if you are a Kanata user, you can check out the work-in-progress Kanata config parser at https://github.com/caksoylar/keymap-drawer/tree/kanata and related issue #95.

Features

Drawing

  • Breaking change: Truncate legends when they are too long:
    • Number of lines in the tap field is truncated to at most 3; if >3, 3rd line will be replaced with
    • Length of each legend (in a single line) is truncated to 1.7 × draw_cfg.shrink_wide_legends (by default 11) chars. If longer than that, the last visible char will be replaced with , similar to above

Fixes

  • Fix parsing of devicetree arrays when they are split to multiple lines and multiple <...> blocks

Misc

  • Add Ferris physical layout with rotated thumb keys, applying to all Ferris/Sweep variants
    • This will be used by default; if you don't want this you can use the original info.json with keymap draw --qmk-info-json argument, or the new "Layout Override" dialog in the web app
  • Add Swoop physical layout
  • Add support for generic physical layouts via layout: {qmk_keyboard: generic/<layout_name>}, which are specially fetched from https://github.com/qmk/qmk_firmware/tree/master/layouts/default/ (where layout_name is a subfolder name)

Full Changelog: v0.16.0...v0.17.0

v0.16.0: Dark mode and modifier functions parsing

15 Apr 03:38
Compare
Choose a tag to compare

This release contains two major new features: parsing of modifier functions and dark mode support! It also contains a couple of smaller breaking changes, so make sure to check them out below.

Features

Parsing

  • Added support for parsing modifier functions like LC(V) in ZMK and LCTL(KC_V) in QMK, used for sending modified keycodes like ctrl+v events with one key press
    • By default these will be converted to Ctl+ V representation, this is configurable via the new parse_config.modifier_fn_map setting
    • You can also assign special names to specific mod combinations, like Hyper+ X for LC(LS(LG(LA(X))))
    • Breaking change: If you were using entries like LC(V): Paste in parse_config.zmk_keycode_map or C(V): Paste in qmk_keycode_map, they will no longer work because LC and V parts are processed separately. If you want to preserve the mapping, instead define them in raw_binding_map like &kp LC(V): Paste for ZMK or C(KC_V): Paste for QMK.
  • Added parsing for QMK tap-toggle layers TT(LAYER) by @m-demare in #87

Drawing

  • Added dark mode support, by @snoyer!
    • This is implemented as a special set of CSS overrides that get added to the final CSS if the new draw_config.dark_mode setting is on, or added under @media (prefers-color-scheme: dark) when set to "auto" to fit the web page or OS light/dark setting.
    • The default is false which means light mode only, so this is not a breaking change for CLI users. The web app overrides it to "auto".
dark_mode: false dark_mode: true dark_mode: auto
logo_light logo_dark logo
  • Added support for appending footer text to produced SVGs using draw_config.footer_text

    • The value goes into a <text> element but it isn't escaped, so you can add e.g. links using <a> tags
    • The default value is empty so this isn't a breaking change for CLI users. The web app overrides it to "Created with keymap-drawer"
  • Added support for using Phosphor Icons, check out how to use them in the README section

CLI

  • Added -o/--output parameter to all keymap subcommands, to write their output to the given path rather than stdout
    • Using these parameters are recommended if you are running the CLI on Windows, since they ensure the outputs are written with utf-8 encoding rather than the locale-specific one (which can break many things). This release also incorporates a couple fixes that ensure operation in Windows (tested in powershell)
    • Breaking change: keymap draw --ortho-layout no longer supports the -o short form since that is taken over by the output parameter

Full Changelog: v0.15.0...v0.16.0

v0.15.0: QMK keyboard mapping

01 Apr 06:29
Compare
Choose a tag to compare

This is a smaller release with a couple of features that I wanted to release quickly: Automatic QMK keyboard mappings and changes to the config dumping.

Features

  • Breaking change: Added a new mapping layer for QMK keyboard names
    • This allows us to map given QMK keyboard name prefixes to other keyboard names during drawing
    • It is currently used to map Corne, Lily58, Sofle and Kyria variants to the versions with rotated keys in qmk_layouts folder
    • This is a breaking change if you were using e.g. qmk_keyboard: crkbd/rev1 rather than qmk_keyboard: corne_rotated -- there is no way to prevent this mapping right now, so let me know if you really want the old behavior instead
  • Breaking change: Config dumps via keymap dump-config no longer include certain "internal" draw config options, namely svg_style, glyph_urls and use_local_cache
    • The rationale is that these shouldn't typically touched by users, and having them be present in all configs creates issues when default values change (such as when #78 is fixed)
    • You can still override them in your config by manually including the keys, the functionality didn't change

Fixes

  • Specially parse 0xff as a special value in the layers property of the combo spec in ZMK keymaps, to mean all layers. This is used by nodefree-config

Misc

  • Add Kyria physical layout with rotated keys, by @micampe
  • Log what config args are used during ZMK drawing workflow

Full Changelog: v0.14.1...v0.15.0

v0.14.x: Cols+thumbs notation, and more

23 Mar 19:43
Compare
Choose a tag to compare

It has been some time since the last release so this release is mostly a collection of smaller improvements, a lot of them contributed by the community (thanks!).

You might have noticed we also have a logo now, itself generated in keymap-drawer!1
KD logo

Features

Parsing

  • Support parsing of overridden node properties with &nodelabel { prop = "new_value"; }; syntax (#66)

Drawing

  • Add a new way to specify physical layouts: "Cols+Thumbs" notation! This generates layouts with only non-rotated 1u keys, but it is significantly more flexible than ortho_layout. It supports columns with arbitrary number of keys, moving the thumb clusters left/right, asymmetric and 2+ number of split keyboard parts.
    See the documentation in the keymap spec to start using.
  • Assign key.type to the CSS class of combos by @englmaxi in #73
  • Add a thin gray outline to combo boxes, to be consistent with key styling and look better

ZMK workflow

  • Add workflow input for base path for <keymap>.json layout files by @michaelrommel in #71
  • Add published artifacts as a destination option by @michaelrommel in #72
  • Add a workflow input to fail GitHub action on parse/draw errors by @englmaxi in #74

Fixes

  • Update Tabler glyphs url that changed (again) by @thebino in #79
  • Use bounding boxes of combo boxes to properly calculate layer heights, to fix rendering issues with small draw_config.outer_pad_h values (#70)
  • Disallow using unrecognized fields in layer key specs or combo specs in keymap YAMLs

Misc

  • Add kilipan/zilpzalp keyboard by @kilipan in #68
  • Add BastardKB boards by @finrod09 in #76
  • Add ZSA Voyager layout by @stasmarkin in #75
  • Upgrade Pydantic to version 2.x, along with other dev dependencies

Full Changelog: v0.13.4...v0.14.0


  1. Here is the source keymap YAML for posterity:

    draw_config:
      append_colon_to_layer_header: false
      svg_extra_style: "text.key { font-weight: bold; font-size: 16px; }"
      glyph_tap_size: 16
    layers:
      " ": [keymap, drawer]
    combos:
      - {p: [0, 1], k: $$mdi:keyboard$$, a: bottom, o: 0.15, arc_scale: 1.2}
      - {p: [0, 1], k: $$mdi:pencil-ruler$$, a: top, o: -0.15, d: false}

    And layout json:

    [
      { "x": 0, "y": 0, "w": 1.2, "h": 1.2, "r":  15, "rx": 1.2, "ry": 0 },
      { "x": 1.2, "y": 0, "w": 1.2, "h": 1.2, "r": -15, "rx": 1.2, "ry": 0 }
    ]

v0.13.x: Parsing tweaks and new combo configs

06 Dec 01:46
Compare
Choose a tag to compare

This release has a few fixes, adds more combo options to customize drawing and new ways to customize the ZMK parsing behavior.

Features

Parsing

  • Add parsing for toggled keys, i.e.. &tog, &to, &kt for ZMK, TG, TO, DF for QMK
  • Add a way to customize how keymap-drawer parses ZMK keymaps, via the KEYMAP_DRAWER define
    • The ZMK parser now defines this symbol before parsing
    • You can use it to add keymap-drawer-specific defines without affecting the ZMK build via #ifdef KEYMAP_DRAWER ... #endif guards
    • You can use it to have keymap-drawer ignore certain parts without affecting the ZMK build via #ifndef KEYMAP_DRAWER ... #endif guards
  • Add a way to specify prefixes to be removed from keycodes before further processing, via parse_config.qmk_remove_keycode_prefix and parse_config.zmk_remove_keycode_prefix
    • See example in #50 (comment) on how to combine above these two features to better handle locale headers like the ones generated via zmk-locale-generator
    • This feature broke parse_config.trans_legend in v0.13.0, fixed in v0.13.1 (#62)

Drawing

  • Add rotation (r) field to the combo spec so you can individually rotate combo boxes -- this is in addition to width, height properties from v0.12.0
  • Also add draw_separate field to the combo spec to let you decide whether you want a combo to be drawn on the layers, or using a separate diagram for that combo

Fixes

  • Add support for using display-name in addition to label for figuring out ZMK layer names
  • Calculate the total layer height (which can be increased due to combo boxes) in the correct way, rather than doing a rough approximation
  • Fix bug during glyph aspect ratio calculation which led to small glyphs for $$material:...$$ SVGs -- thanks to @dhruvinsh for the bringing up the issue (and sorry for the late fix)
  • Fix APOS/APOSTROPHE mapping in default zmk_keycode_map
  • Update Tabler template URL to fetch SVGs from using $$tabler:...$$ in v0.13.2, since the previous one doesn't seem to work anymore

Misc

  • Added user friendly(-er) configuration reference at CONFIGURATION.md
  • Fix layout mapping for luna keyboard and make it use the splayed Hummingbird variant
  • Add layouts for BastardKB Dilemma v2 and MAX, overriding the defaults when used with qmk_keyboard: bastardkb/dilemma/3x5_3 and qmk_keyboard: bastardkb/dilemma/4x6_4, by @casuanoob
  • Add layout mapping for wizza

Looking forward

One feature that I have been working on some time is parsing for modified keys, to automatically convert keycodes like &kp LC(LS(A)) to strings like Ctrl+Shift+A. While the implementation is complete and the end result is configurable, I still haven't reached a decision on the default configuration for how to do the conversion so I haven't merged it to the main branch. I iterated through a few variations, e.g.

  • Ctrl+Shift+ A resulting in A rendered on a separate line (default in the implementation)
    • Also automatically uses Hyper and Meh for the appropriate mod combinations
  • CS+A
  • C-S-A
  • Using Mac-like symbols like ⎈⇧A

You can test this feature in the dev branch (also deployed to streamlit) and let me know your opinions/suggestions in the discussion linked to this release.

Full Changelog: v0.12.1...v0.13.1

v0.12.0 and v0.12.1

20 Oct 20:50
Compare
Choose a tag to compare

This release contains a couple minor features, a few fixes and some physical layout updates for ZMK keyboards.

Features

  • Add per-combo width (w) and height (h) field support. Defaults to draw_config.combo_w/draw_config.combo_h if they aren't specified or are null
  • Add draw_config.svg_extra_style config that gets appended to draw_config.svg_style. This way you don't need to duplicate and modify draw_config.svg_style in your configuration and can simply add your overrides to draw_config.svg_extra_style

Fixes

  • Fix invalid SVG error when using special char in layer labels by @HelloThisIsFlo in #55
  • Move workflow write permission field from workflow file to usage example

Misc

  • Add a Sofle layout with rotated thumb keys by @YellowAfterlife in #46
  • Fix FFKB coordinates order by @jaeyounglee978 in #52
  • Add physical layouts support for keyboards designed by @hazels-garage and @cyril279
  • Fix Glove80 thumb cluster layout
    • Key ordering broken in v0.12.0 and then fixed in v0.12.1
  • Add support for a few new ZMK shields: microdox_v2, reviung34, reviung53, fixed tidbit

Full Changelog: v0.11.0...v0.12.1

v0.11.0: New drawing features

29 Aug 01:50
Compare
Choose a tag to compare

This release introduces a few major drawing features, automated ZMK workflow improvements and a major internal refactor to improve the project structure.

Features

  • Multiple output columns!

    • Set the draw_config.n_columns variable to e.g. 3 to output with three layer columns

    image

  • Separate combo diagrams! For those of you who use thumb+alpha combos or steno-like keymaps, there is now the option
    to draw each combo in a separate minified layer diagram, showing the output key and the triggering key positions.

    • Set draw_config.separate_combo_diagrams: true to enable, and draw_config.combo_diagrams_scale to tweak the scaling factor (default 2)
    • Currently the layers property of the combos are ignored and not visualized, might be added in the future if there is a clean way to show it
    • Key corner radii are currently not scaled, so the keys will look rounder for higher scale factors

    image

  • Add key sides to drawn keys to give a keycap "profile" appearance, by @riccardoflp

    • draw_config.draw_key_sides: true to enable, tweak the appearance via draw_config.key_side_pars
    • Currently may not render well on Safari, looking into workarounds

    image

Fixes

  • Sort SVG glyph defs before writing to avoid non-deterministic output
  • Tweak Tabler-related CSS to hide the outline boxes in Safari, by @bryanforbes
  • Fix font size issue in hold/shifted fields due to draw_config.shrink_wide_legends, by inxi (at MoErgo Discord)
  • Fix issue creating unnecessarily long dendrons for certain combo types

ZMK drawing workflow

Misc

  • Tweak classes for output SVG elements to allow for better customization via CSS
    • Assign key/combo classes to rect+text elements for layout keys/combos
    • Assign keypos-N/combopos-N classes to key/combo elts. to allow addressing via position index N
  • Add a proper physical layout for slicemk_ergodox, by @xudongzheng
  • Round SVG coordinate/size values for better readability and smaller output size, by @art4ride and me

Note that future updates might unfortunately include more CSS changes, such as converting to the descendants selector syntax, e.g. .held rect { ... } from rect.held { ... }. Thanks to the folks at LowProKB and MoErgo for helpful discussions.

I will also prioritize a better documentation organization in the short term, possibly hosted on Github pages.

Full Changelog: v0.10.0...v0.11.0