qmk-skim 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. qmk_skim-0.4.1/PKG-INFO +111 -0
  2. qmk_skim-0.4.1/README.md +87 -0
  3. qmk_skim-0.4.1/pyproject.toml +121 -0
  4. qmk_skim-0.4.1/src/skim/__init__.py +40 -0
  5. qmk_skim-0.4.1/src/skim/application/__init__.py +0 -0
  6. qmk_skim-0.4.1/src/skim/application/config_generator.py +159 -0
  7. qmk_skim-0.4.1/src/skim/application/image_generator.py +456 -0
  8. qmk_skim-0.4.1/src/skim/application/keycode_loader.py +132 -0
  9. qmk_skim-0.4.1/src/skim/application/keycode_transformer.py +343 -0
  10. qmk_skim-0.4.1/src/skim/application/layer_transformer.py +153 -0
  11. qmk_skim-0.4.1/src/skim/application/parsers/c2json_parser.py +87 -0
  12. qmk_skim-0.4.1/src/skim/application/parsers/keybard_parser.py +139 -0
  13. qmk_skim-0.4.1/src/skim/application/parsers/qmk_color_parser.py +89 -0
  14. qmk_skim-0.4.1/src/skim/application/parsers/vial_parser.py +93 -0
  15. qmk_skim-0.4.1/src/skim/application/typst_compiler.py +98 -0
  16. qmk_skim-0.4.1/src/skim/assets/data/default-config.yaml +31 -0
  17. qmk_skim-0.4.1/src/skim/assets/data/keycode-mappings.yaml +502 -0
  18. qmk_skim-0.4.1/src/skim/assets/typst/fonts/Roboto-Black.ttf +0 -0
  19. qmk_skim-0.4.1/src/skim/assets/typst/fonts/Roboto-Regular.ttf +0 -0
  20. qmk_skim-0.4.1/src/skim/assets/typst/fonts/Roboto-Thin.ttf +0 -0
  21. qmk_skim-0.4.1/src/skim/assets/typst/fonts/SymbolsNerdFontMono-Regular.ttf +0 -0
  22. qmk_skim-0.4.1/src/skim/assets/typst/keymap-layers.typ +37 -0
  23. qmk_skim-0.4.1/src/skim/assets/typst/keymap-overview.typ +130 -0
  24. qmk_skim-0.4.1/src/skim/assets/typst/svalboard-keys.typ +756 -0
  25. qmk_skim-0.4.1/src/skim/assets/typst/svalboard-logo.svg +21 -0
  26. qmk_skim-0.4.1/src/skim/domain/__init__.py +5 -0
  27. qmk_skim-0.4.1/src/skim/domain/colors.py +158 -0
  28. qmk_skim-0.4.1/src/skim/domain/config.py +382 -0
  29. qmk_skim-0.4.1/src/skim/domain/models.py +202 -0
  30. qmk_skim-0.4.1/src/skim/ui/cli.py +276 -0
  31. qmk_skim-0.4.1/src/skim/ui/logging_config.py +138 -0
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.3
2
+ Name: qmk-skim
3
+ Version: 0.4.1
4
+ Summary: Svalboard Keymap Image Maker
5
+ Keywords: svalboard,keyboard,keymap,layout,image,svg,png,typst
6
+ Author: Thiago Alves
7
+ Author-email: Thiago Alves <thiago@rapinialves.com>
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: End Users/Desktop
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Multimedia :: Graphics
18
+ Classifier: Topic :: Utilities
19
+ Requires-Dist: click>=8.1.0
20
+ Requires-Dist: pyyaml>=6.0
21
+ Requires-Dist: typst>=0.12.0
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+
25
+ # Svalboard Keymap Image Maker (skim)
26
+
27
+ [![Coverage](https://img.shields.io/badge/coverage-96%25-brightgreen.svg)](https://github.com/Townk/skim)
28
+ [![Python Version](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/)
29
+ [![Build Status](https://github.com/Townk/skim/actions/workflows/prerelease.yml/badge.svg)](https://github.com/Townk/skim/actions/workflows/prerelease.yml)
30
+ [![PyPI version](https://badge.fury.io/py/qmk-skim.svg)](https://badge.fury.io/py/qmk-skim)
31
+
32
+ A Python CLI tool for generating keymap layout images for the [Svalboard](https://svalboard.com) keyboard.
33
+
34
+ ## Features
35
+
36
+ - Generate individual layer keymap images
37
+ - Generate overview images showing all layers
38
+ - Support for multiple keymap formats:
39
+ - Keybard (`.kbi`)
40
+ - Vial (`.vil`)
41
+ - QMK c2json (`.json`)
42
+ - Configurable colors and appearance
43
+ - High-quality SVG and PNG output
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ pip install skim
49
+ ```
50
+
51
+ ## Usage
52
+
53
+ ### Generate keymap images
54
+
55
+ ```bash
56
+ # Generate from a keymap file
57
+ skim generate --keymap my-keymap.kbi --output-dir ./images
58
+
59
+ # Generate with custom configuration
60
+ skim generate --keymap my-keymap.kbi --config skim-config.yaml --output-dir ./images
61
+
62
+ # Generate specific layers only
63
+ skim generate --keymap my-keymap.kbi --layer 1 --layer 3-5 --layer overview
64
+ ```
65
+
66
+ ### Configuration helper
67
+
68
+ ```bash
69
+ # Create a configuration file from QMK color.h
70
+ skim configure --qmk-color-header /path/to/qmk/quantum/color.h --output skim-config.yaml
71
+ ```
72
+
73
+ ## Development
74
+
75
+ ### Setup
76
+
77
+ ```bash
78
+ # Clone the repository
79
+ git clone https://github.com/your-repo/skim.git
80
+ cd skim
81
+
82
+ # Create virtual environment and install dependencies
83
+ uv venv
84
+ source .venv/bin/activate # or .venv\Scripts\activate on Windows
85
+ uv sync --dev
86
+ ```
87
+
88
+ ### Testing
89
+
90
+ ```bash
91
+ # Run tests with coverage
92
+ uv run pytest
93
+
94
+ # Run specific test file
95
+ uv run pytest tests/unit/domain/test_colors.py
96
+ ```
97
+
98
+ ### Building Documentation
99
+
100
+ ```bash
101
+ cd docs
102
+ sphinx-build -b html . _build
103
+ ```
104
+
105
+ ## License
106
+
107
+ MIT License
108
+
109
+ ## Contributing
110
+
111
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,87 @@
1
+ # Svalboard Keymap Image Maker (skim)
2
+
3
+ [![Coverage](https://img.shields.io/badge/coverage-96%25-brightgreen.svg)](https://github.com/Townk/skim)
4
+ [![Python Version](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/)
5
+ [![Build Status](https://github.com/Townk/skim/actions/workflows/prerelease.yml/badge.svg)](https://github.com/Townk/skim/actions/workflows/prerelease.yml)
6
+ [![PyPI version](https://badge.fury.io/py/qmk-skim.svg)](https://badge.fury.io/py/qmk-skim)
7
+
8
+ A Python CLI tool for generating keymap layout images for the [Svalboard](https://svalboard.com) keyboard.
9
+
10
+ ## Features
11
+
12
+ - Generate individual layer keymap images
13
+ - Generate overview images showing all layers
14
+ - Support for multiple keymap formats:
15
+ - Keybard (`.kbi`)
16
+ - Vial (`.vil`)
17
+ - QMK c2json (`.json`)
18
+ - Configurable colors and appearance
19
+ - High-quality SVG and PNG output
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ pip install skim
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ### Generate keymap images
30
+
31
+ ```bash
32
+ # Generate from a keymap file
33
+ skim generate --keymap my-keymap.kbi --output-dir ./images
34
+
35
+ # Generate with custom configuration
36
+ skim generate --keymap my-keymap.kbi --config skim-config.yaml --output-dir ./images
37
+
38
+ # Generate specific layers only
39
+ skim generate --keymap my-keymap.kbi --layer 1 --layer 3-5 --layer overview
40
+ ```
41
+
42
+ ### Configuration helper
43
+
44
+ ```bash
45
+ # Create a configuration file from QMK color.h
46
+ skim configure --qmk-color-header /path/to/qmk/quantum/color.h --output skim-config.yaml
47
+ ```
48
+
49
+ ## Development
50
+
51
+ ### Setup
52
+
53
+ ```bash
54
+ # Clone the repository
55
+ git clone https://github.com/your-repo/skim.git
56
+ cd skim
57
+
58
+ # Create virtual environment and install dependencies
59
+ uv venv
60
+ source .venv/bin/activate # or .venv\Scripts\activate on Windows
61
+ uv sync --dev
62
+ ```
63
+
64
+ ### Testing
65
+
66
+ ```bash
67
+ # Run tests with coverage
68
+ uv run pytest
69
+
70
+ # Run specific test file
71
+ uv run pytest tests/unit/domain/test_colors.py
72
+ ```
73
+
74
+ ### Building Documentation
75
+
76
+ ```bash
77
+ cd docs
78
+ sphinx-build -b html . _build
79
+ ```
80
+
81
+ ## License
82
+
83
+ MIT License
84
+
85
+ ## Contributing
86
+
87
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,121 @@
1
+ [project]
2
+ name = "qmk-skim"
3
+ version = "0.4.1"
4
+ description = "Svalboard Keymap Image Maker"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Thiago Alves", email = "thiago@rapinialves.com" }
8
+ ]
9
+ keywords = ["svalboard", "keyboard", "keymap", "layout", "image", "svg", "png", "typst"]
10
+ classifiers = [
11
+ "Development Status :: 3 - Alpha",
12
+ "Environment :: Console",
13
+ "Intended Audience :: End Users/Desktop",
14
+ "License :: OSI Approved :: MIT License",
15
+ "Operating System :: OS Independent",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Topic :: Multimedia :: Graphics",
21
+ "Topic :: Utilities",
22
+ ]
23
+ requires-python = ">=3.10"
24
+ dependencies = [
25
+ "click>=8.1.0",
26
+ "pyyaml>=6.0",
27
+ "typst>=0.12.0",
28
+ ]
29
+
30
+ [project.scripts]
31
+ skim = "skim.ui.cli:main"
32
+
33
+ [tool.pytest.ini_options]
34
+ testpaths = ["tests"]
35
+ python_files = ["test_*.py"]
36
+ python_classes = ["Test*"]
37
+ python_functions = ["test_*"]
38
+ addopts = "--cov=skim --cov-report=html --cov-report=term-missing"
39
+ minversion = "8.0"
40
+
41
+ [tool.coverage.run]
42
+ source = ["src"]
43
+ omit = ["*/tests/*", "*/__pycache__/*"]
44
+
45
+ [tool.coverage.report]
46
+ exclude_lines = [
47
+ "pragma: no cover",
48
+ "def __repr__",
49
+ "if __name__ == .__main__.:",
50
+ "raise AssertionError",
51
+ "raise NotImplementedError",
52
+ ]
53
+ fail_under = 95
54
+
55
+ [tool.ruff]
56
+ target-version = "py310"
57
+ line-length = 88
58
+ src = ["src", "tests"]
59
+
60
+ [tool.ruff.lint]
61
+ select = [
62
+ "E", # pycodestyle errors
63
+ "W", # pycodestyle warnings
64
+ "F", # Pyflakes
65
+ "I", # isort
66
+ "B", # flake8-bugbear
67
+ "C4", # flake8-comprehensions
68
+ "UP", # pyupgrade
69
+ "ARG", # flake8-unused-arguments
70
+ "SIM", # flake8-simplify
71
+ ]
72
+ ignore = [
73
+ "E501", # line too long (handled by formatter)
74
+ "B008", # do not perform function calls in argument defaults
75
+ "C901", # too complex
76
+ "ARG001", # unused function argument
77
+ "ARG002", # unused method argument
78
+ ]
79
+
80
+ [tool.ruff.lint.isort]
81
+ known-first-party = ["skim"]
82
+ force-single-line = false
83
+ combine-as-imports = true
84
+
85
+ [tool.ruff.format]
86
+ quote-style = "double"
87
+ indent-style = "space"
88
+ skip-magic-trailing-comma = false
89
+ line-ending = "auto"
90
+ docstring-code-format = true
91
+
92
+ [tool.basedpyright]
93
+ pythonVersion = "3.10"
94
+ typeCheckingMode = "standard"
95
+ include = ["src"]
96
+ exclude = ["**/node_modules", "**/__pycache__", ".git", "build", "dist"]
97
+ reportMissingImports = true
98
+ reportMissingTypeStubs = false
99
+ reportUnusedImport = true
100
+ reportUnusedVariable = true
101
+
102
+ [build-system]
103
+ requires = ["uv_build>=0.9.22,<0.10.0"]
104
+ build-backend = "uv_build"
105
+
106
+ [tool.uv.build-backend]
107
+ module-name = "skim"
108
+
109
+ [dependency-groups]
110
+ dev = [
111
+ "pytest>=9.0.2",
112
+ "pytest-cov>=7.0.0",
113
+ "ruff>=0.8.0",
114
+ "basedpyright>=1.22.0",
115
+ ]
116
+ docs = [
117
+ "sphinx>=8.1.3",
118
+ "furo>=2024.0.0",
119
+ "sphinx-autodoc-typehints>=2.0.0",
120
+ "myst-parser>=3.0.0",
121
+ ]
@@ -0,0 +1,40 @@
1
+ """Skim - Svalboard Keymap Image Maker.
2
+
3
+ A command-line tool for generating visual keyboard layout images from QMK,
4
+ Vial, and Keybard keymap files. Skim parses keymap definitions and produces
5
+ high-quality SVG or PNG images suitable for documentation, reference cards,
6
+ or sharing keyboard layouts.
7
+
8
+ Example:
9
+ Generate images from a keymap file::
10
+
11
+ $ skim generate --keymap my-layout.kbi --output-dir ./images
12
+
13
+ Generate with custom configuration::
14
+
15
+ $ skim generate -k layout.vil -c config.yaml -o ./out -f png
16
+
17
+ Create a configuration from a Keybard file::
18
+
19
+ $ skim configure -k my-layout.kbi -o skim-config.yaml
20
+ """
21
+
22
+ from importlib.metadata import metadata
23
+
24
+ _metadata = metadata("qmk-skim")
25
+ __version__ = _metadata["Version"]
26
+ __prog_name__ = f"{_metadata['Summary']} ({_metadata['Name']})"
27
+
28
+
29
+ def main() -> None:
30
+ """Entry point placeholder for the skim package.
31
+
32
+ This function serves as a simple entry point for package verification.
33
+ The actual CLI functionality is provided by the :mod:`skim.ui.cli` module
34
+ through Click commands.
35
+
36
+ Note:
37
+ For CLI usage, invoke ``skim`` directly or use
38
+ ``python -m skim.ui.cli``.
39
+ """
40
+ print("Hello from skim!")
File without changes
@@ -0,0 +1,159 @@
1
+ """Configuration Generator for creating Skim config from source files.
2
+
3
+ This module provides the :class:`ConfigGenerator` which extracts metadata
4
+ from Keybard keymap files and QMK color headers to generate Skim YAML
5
+ configuration files. This automates the initial configuration setup
6
+ for users migrating from these tools.
7
+
8
+ The generator extracts:
9
+ - Layer colors (converted from HSV to hex)
10
+ - Layer names from cosmetic settings
11
+ - Custom keycode short names for display labels
12
+ - Named color definitions from QMK headers
13
+
14
+ Example:
15
+ Generating configuration from a Keybard file::
16
+
17
+ generator = ConfigGenerator()
18
+ yaml_config = generator.generate(
19
+ keybard_content=keybard_json_str,
20
+ qmk_header_content=qmk_color_h_content,
21
+ adjust_lightness=0.31,
22
+ )
23
+ Path("skim-config.yaml").write_text(yaml_config)
24
+ """
25
+
26
+ import colorsys
27
+ import re
28
+
29
+ import yaml
30
+
31
+ from skim.application.parsers.keybard_parser import KeybardParser
32
+ from skim.application.parsers.qmk_color_parser import QmkColorParser
33
+ from skim.domain.colors import adjust_color, hex_str
34
+
35
+
36
+ class ConfigGenerator:
37
+ """Generates Skim configuration YAML from source keymap files.
38
+
39
+ This class extracts relevant metadata from Keybard (.kbi) files and
40
+ optional QMK color headers to produce a ready-to-use Skim configuration.
41
+ The generated config includes layer definitions, color schemes, and
42
+ keycode display overrides.
43
+
44
+ Example:
45
+ >>> generator = ConfigGenerator()
46
+ >>> yaml_output = generator.generate(keybard_content)
47
+ >>> print(yaml_output)
48
+ layers:
49
+ - base_color: '#347156'
50
+ label: BASE
51
+ name: Base
52
+ id: '0'
53
+ ...
54
+ """
55
+
56
+ def generate(
57
+ self,
58
+ keybard_content: str,
59
+ qmk_header_content: str | None = None,
60
+ adjust_lightness: float | None = None,
61
+ adjust_saturation: float | None = None,
62
+ ) -> str:
63
+ """Generate YAML configuration from Keybard content.
64
+
65
+ Parses the Keybard JSON file to extract layer colors, names, and
66
+ custom keycode definitions. Optionally integrates QMK color
67
+ definitions from a color.h header file.
68
+
69
+ Args:
70
+ keybard_content: JSON string content of the Keybard .kbi file.
71
+ qmk_header_content: Optional C header content from QMK color.h
72
+ file containing RGB_* and HSV_* color definitions.
73
+ adjust_lightness: Optional target lightness (0.0-1.0) to apply
74
+ to all extracted colors. Useful for ensuring readable
75
+ contrast in generated images.
76
+ adjust_saturation: Optional maximum saturation (0.0-1.0) to cap
77
+ all extracted colors. Original saturation is reduced to
78
+ this value if it exceeds the target.
79
+
80
+ Returns:
81
+ YAML-formatted string containing the generated Skim configuration.
82
+ Ready to be written to a .yaml file.
83
+
84
+ Raises:
85
+ ValueError: If keybard_content contains invalid JSON.
86
+
87
+ Example:
88
+ >>> generator = ConfigGenerator()
89
+ >>> config = generator.generate(
90
+ ... keybard_content=Path("layout.kbi").read_text(),
91
+ ... qmk_header_content=Path("color.h").read_text(),
92
+ ... adjust_lightness=0.31,
93
+ ... )
94
+ >>> Path("skim-config.yaml").write_text(config)
95
+ """
96
+ parser = KeybardParser()
97
+ metadata = parser.extract_metadata(keybard_content)
98
+
99
+ def apply_adjustment(hex_c: str) -> str:
100
+ if adjust_lightness is not None or adjust_saturation is not None:
101
+ return adjust_color(hex_c, adjust_lightness, adjust_saturation)
102
+ return hex_c
103
+
104
+ qmk_colors = {}
105
+ if qmk_header_content:
106
+ qmk_parser = QmkColorParser()
107
+ qmk_colors = qmk_parser.parse(qmk_header_content)
108
+ for k, v in qmk_colors.items():
109
+ qmk_colors[k] = apply_adjustment(v)
110
+
111
+ layers_config = []
112
+ layer_colors = metadata.get("layer_colors", [])
113
+ layer_names = metadata.get("layer_names", {})
114
+
115
+ for idx, color_data in enumerate(layer_colors):
116
+ h = color_data.get("hue", 0) / 255.0
117
+ s = color_data.get("sat", 255) / 255.0
118
+ v = color_data.get("val", 255) / 255.0
119
+
120
+ r, g, b = colorsys.hsv_to_rgb(h, s, v)
121
+ base_color = hex_str(r, g, b)
122
+ base_color = apply_adjustment(base_color)
123
+
124
+ idx_str = str(idx)
125
+ name = layer_names.get(idx_str, f"Layer {idx}")
126
+
127
+ layer_entry = {
128
+ "base_color": base_color,
129
+ "label": name.upper()[:4].strip(),
130
+ "name": name,
131
+ "id": str(idx),
132
+ }
133
+ layers_config.append(layer_entry)
134
+
135
+ overrides = {}
136
+ for item in metadata.get("custom_keycodes", []):
137
+ if "name" in item and "shortName" in item:
138
+ short_name = item["shortName"]
139
+ short_name = re.sub(r"\s+", " ", short_name).strip()
140
+ overrides[item["name"]] = short_name
141
+
142
+ config_dict = {
143
+ "layers": layers_config,
144
+ "appearance": {
145
+ "colors": {
146
+ "text": "#000000",
147
+ "background": "#FFFFFF",
148
+ "neutral": "#70768B",
149
+ }
150
+ },
151
+ }
152
+
153
+ if qmk_colors:
154
+ config_dict["appearance"]["colors"]["named_colors"] = qmk_colors
155
+
156
+ if overrides:
157
+ config_dict["keycodes"] = overrides
158
+
159
+ return yaml.dump(config_dict, sort_keys=False)