Skip to content

Commit

Permalink
proper implementation of kalamine create
Browse files Browse the repository at this point in the history
  • Loading branch information
fabi1cazenave committed Feb 11, 2024
1 parent 40f82f7 commit 5190f38
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 67 deletions.
37 changes: 2 additions & 35 deletions kalamine/cli.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
#!/usr/bin/env python3

import json
import pkgutil
from contextlib import contextmanager
from importlib import metadata
from pathlib import Path
from typing import Iterator, List, Literal, Union

import click
import tomli

from .help import TOML_FOOTER, TOML_HEADER, inline_guide, user_guide
from .help import user_guide, create_layout
from .layout import KeyboardLayout, load_layout
from .server import keyboard_server

Expand Down Expand Up @@ -174,38 +172,7 @@ def make(
@click.option("--1dk/--no-1dk", "odk", default=False, help="Set a custom dead key.")
def create(output_file: Path, geometry: str, altgr: bool, odk: bool) -> None:
"""Create a new TOML layout description."""

def get_layout(name: str) -> KeyboardLayout:
"""Return a layout of type NAME with constrained geometry."""
descriptor = pkgutil.get_data(__package__, f"../layouts/{name}.toml")
layout = KeyboardLayout(tomli.loads(descriptor.decode("utf-8"))) # type: ignore
layout.geometry = geometry
return layout

def keymap(layout_name, layout_layer, layer_name=""):
"""Return a multiline keymap ASCII art for the specified layout."""
layer = "\n"
layer += f"\n{layer_name or layout_layer} = '''"
layer += "\n"
layer += "\n".join(getattr(get_layout(layout_name), layout_layer))
layer += "\n'''"
return layer

content = f'{TOML_HEADER}"{geometry.upper()}"'
if odk:
content += keymap("intl", "base")
if altgr:
content += keymap("prog", "altgr")
content += "\n"
content += TOML_FOOTER
elif altgr:
content += keymap("prog", "full")
else:
content += keymap("ansi", "base")

# append user guide sections
with open(output_file, "w", encoding="utf-8", newline="\n") as file:
file.write(content + inline_guide())
create_layout(output_file, geometry, altgr, odk)
click.echo(f"... {output_file}")


Expand Down
62 changes: 62 additions & 0 deletions kalamine/data/layout.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: custom
name8: custom
locale: us
variant: custom
author: nobody
description: QWERTY, custom variant
url: https://OneDeadKey.github.com/kalamine/
version: 0.0.1

alpha: |
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┲━━━━━━━━━━┓
│ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + ┃ ┃
│ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = ┃ ⌫ ┃
┢━━━━━┷━━┱──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┺━━┯━━━━━━━┩
┃ ┃ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ | │
┃ ↹ ┃ │ │ │ │ │ │ │ │ │ │ [ │ ] │ \ │
┣━━━━━━━━┻┱────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┲━━━━┷━━━━━━━┪
┃ ┃ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ " ┃ ┃
┃ ⇬ ┃ │ │ │ │ │ │ │ │ │ ; │ ' ┃ ⏎ ┃
┣━━━━━━━━━┻━━┱──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┲━━┻━━━━━━━━━━━━┫
┃ ┃ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? ┃ ┃
┃ ⇧ ┃ │ │ │ │ │ │ │ , │ . │ / ┃ ⇧ ┃
┣━━━━━━━┳━━━━┻━━┳━━┷━━━━┱┴─────┴─────┴─────┴─────┴─────┴─┲━━━┷━━━┳━┷━━━━━╋━━━━━━━┳━━━━━━━┫
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
┃ Ctrl ┃ super ┃ Alt ┃ ␣ ┃ Alt ┃ super ┃ menu ┃ Ctrl ┃
┗━━━━━━━┻━━━━━━━┻━━━━━━━┹────────────────────────────────┺━━━━━━━┻━━━━━━━┻━━━━━━━┻━━━━━━━┛
1dk: |
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┲━━━━━━━━━━┓
│ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + ┃ ┃
│ ` │ 1 │ 2 « │ 3 » │ 4 │ 5 € │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = ┃ ⌫ ┃
┢━━━━━┷━━┱──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┺━━┯━━━━━━━┩
┃ ┃ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ | │
┃ ↹ ┃ │ │ é │ │ │ ý │ ú │ í │ ó │ │ [ │ ] │ \ │
┣━━━━━━━━┻┱────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┲━━━━┷━━━━━━━┪
┃ ┃ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │*¨ ┃ ┃
┃ ⇬ ┃ á │ │ │ │ │ │ │ │ │ ; │** ' ┃ ⏎ ┃
┣━━━━━━━━━┻━━┱──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┲━━┻━━━━━━━━━━━━┫
┃ ┃ Z │ X │ C │ V │ B │ N │ M │ < • │ > │ ? ┃ ┃
┃ ⇧ ┃ │ │ ç │ │ │ │ µ │ , · │ . … │ / ┃ ⇧ ┃
┣━━━━━━━┳━━━━┻━━┳━━┷━━━━┱┴─────┴─────┴─────┴─────┴─────┴─┲━━━┷━━━┳━┷━━━━━╋━━━━━━━┳━━━━━━━┫
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
┃ Ctrl ┃ super ┃ Alt ┃ ␣ ┃ Alt ┃ super ┃ menu ┃ Ctrl ┃
┗━━━━━━━┻━━━━━━━┻━━━━━━━┹────────────────────────────────┺━━━━━━━┻━━━━━━━┻━━━━━━━┻━━━━━━━┛
altgr: |
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┲━━━━━━━━━━┓
│ *~ │ │ │ │ │ │ │ │ │ │ │ │ ┃ ┃
│ *` │ │ │ │ │ │ *^ │ │ │ │ │ │ ┃ ⌫ ┃
┢━━━━━┷━━┱──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┺━━┯━━━━━━━┩
┃ ┃ │ │ │ │ │ │ │ │ │ │ │ │ │
┃ ↹ ┃ @ │ < │ > │ $ │ % │ ^ │ & │ * │ ' │ ` │ │ │ │
┣━━━━━━━━┻┱────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┲━━━━┷━━━━━━━┪
┃ ┃ │ │ │ │ │ │ │ │ │ │ *¨ ┃ ┃
┃ ⇬ ┃ { │ ( │ ) │ } │ = │ \ │ + │ - │ / │ " │ *' ┃ ⏎ ┃
┣━━━━━━━━━┻━━┱──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┲━━┻━━━━━━━━━━━━┫
┃ ┃ │ │ │ │ │ │ │ │ │ ┃ ┃
┃ ⇧ ┃ ~ │ [ │ ] │ _ │ # │ | │ ! │ ; │ : │ ? ┃ ⇧ ┃
┣━━━━━━━┳━━━━┻━━┳━━┷━━━━┱┴─────┴─────┴─────┴─────┴─────┴─┲━━━┷━━━┳━┷━━━━━╋━━━━━━━┳━━━━━━━┫
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
┃ Ctrl ┃ super ┃ Alt ┃ ␣ ┃ AltGr ┃ super ┃ menu ┃ Ctrl ┃
┗━━━━━━━┻━━━━━━━┻━━━━━━━┹────────────────────────────────┺━━━━━━━┻━━━━━━━┻━━━━━━━┻━━━━━━━┛
94 changes: 69 additions & 25 deletions kalamine/help.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,23 @@
import pkgutil
from pathlib import Path
from typing import List

import yaml

from .layout import KeyboardLayout
from .utils import load_data

SEPARATOR = "--------------------------------------------------------------------------------"
SEPARATOR = (
"--------------------------------------------------------------------------------"
)

MARKDOWN_HEADER = """Defining a Keyboard Layout
================================================================================
Kalamine keyboard layouts are defined with TOML files including this kind of
ASCII-art layer templates:
```
full = '''
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┲━━━━━━━━━━┓
│ ~*~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + ┃ ┃
│ `*` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6*^ │ 7 │ 8 │ 9 │ 0 │ - │ = ┃ ⌫ ┃
┢━━━━━┷━━┱──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┺━━┯━━━━━━━┩
┃ ┃ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ | │
┃ ↹ ┃ @ │ < │ > │ $ │ % │ ^ │ & │ * │ ' │ ` │ [ │ ] │ \\
┣━━━━━━━━┻┱────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┲━━━━┷━━━━━━━┪
┃ ┃ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ "*¨ ┃ ┃
┃ ⇬ ┃ { │ ( │ ) │ } │ = │ \\ │ + │ - │ / │ ; " │ '*´ ┃ ⏎ ┃
┣━━━━━━━━━┻━━┱──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┲━━┻━━━━━━━━━━━━┫
┃ ┃ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? ┃ ┃
┃ ⇧ ┃ ~ │ [ │ ] │ _ │ # │ | │ ! │ , ; │ . : │ / ? ┃ ⇧ ┃
┣━━━━━━━┳━━━━┻━━┳━━┷━━━━┱┴─────┴─────┴─────┴─────┴─────┴─┲━━━┷━━━┳━┷━━━━━╋━━━━━━━┳━━━━━━━┫
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
┃ Ctrl ┃ super ┃ Alt ┃ ␣ ┃ AltGr ┃ super ┃ menu ┃ Ctrl ┃
┗━━━━━━━┻━━━━━━━┻━━━━━━━┹────────────────────────────────┺━━━━━━━┻━━━━━━━┻━━━━━━━┻━━━━━━━┛
'''
```
```KALAMINE_LAYOUT```
"""

TOML_HEADER = """# kalamine keyboard layout descriptor
Expand Down Expand Up @@ -78,15 +66,71 @@ def core_guide() -> List[str]:
return sections


def draw_layout(geometry: str = "ISO", altgr: bool = False, odk: bool = False) -> str:
"""Draw a ASCII art description of a default layout."""

pkg_file = pkgutil.get_data(__package__, "data/layout.yaml")
if pkg_file is None:
return ""

# load the descriptor bug only keep the leyers we need
descriptor = yaml.safe_load(pkg_file.decode("utf-8"))
if not altgr:
del descriptor["altgr"]
if not odk:
del descriptor["1dk"]
descriptor["base"] = descriptor.pop("alpha")
else:
del descriptor["alpha"]
descriptor["base"] = descriptor.pop("1dk")
descriptor["geometry"] = geometry.upper()

# make a lyaout, just to get the ASCII arts
layout = KeyboardLayout(descriptor)
layout.geometry = geometry

def keymap(layer_name: str) -> str:
layer = "\n".join(getattr(layout, layer_name))
return f"\n{layer_name} = '''\n{layer}\n'''\n"

content = ""
if odk:
content += keymap("base")
if altgr:
content += keymap("altgr")
elif altgr:
content += keymap("full")
else:
content += keymap("base")

return content


###
# Public API
##


def user_guide() -> str:
return MARKDOWN_HEADER + "\n".join(core_guide())
"""Create a user guide with a sample layout description."""

header = MARKDOWN_HEADER.replace(
"KALAMINE_LAYOUT", draw_layout(geometry="ANSI", altgr="true")
)
return header + "\n" + "\n".join(core_guide())


def create_layout(output_file: Path, geometry: str, altgr: bool, odk: bool) -> None:
"""Create a new TOML layout description."""

def inline_guide() -> str:
content: str = ""
content = f'{TOML_HEADER}"{geometry.upper()}"\n'
content += draw_layout(geometry, altgr, odk)
if odk:
content += TOML_FOOTER

for topic in core_guide():
content += f"\n\n\n# {SEPARATOR}"
content += "\n# ".join(topic.rstrip().split("\n"))

return content.replace(" \n", "\n")
with open(output_file, "w", encoding="utf-8", newline="\n") as file:
file.write(content.replace(" \n", "\n"))
2 changes: 1 addition & 1 deletion layouts/ansi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name8 = "q-ansi"
locale = "us"
variant = "ansi"
description = "standard QWERTY-US layout"
url = "http://OneDeadKey.github.com/kalamine/"
url = "https://OneDeadKey.github.com/kalamine/"
version = "1.0.0"
geometry = "ANSI"

Expand Down
2 changes: 1 addition & 1 deletion layouts/intl.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name8 = "q-intl"
locale = "us"
variant = "intl"
description = "QWERTY layout, international variant"
url = "http://OneDeadKey.github.com/kalamine/"
url = "https://OneDeadKey.github.com/kalamine/"
version = "1.0.0"
geometry = "ISO"

Expand Down
2 changes: 1 addition & 1 deletion layouts/prog.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name8 = "q-prog"
variant = "prog"
locale = "us"
description = "QWERTY-intl layout, developer variant"
url = "http://OneDeadKey.github.com/kalamine/"
url = "https://OneDeadKey.github.com/kalamine/"
version = "0.6.0"
geometry = "ANSI"

Expand Down
4 changes: 0 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
requires = ["hatchling"]
build-backend = "hatchling.build"

# XXX distributing this "layouts" directory is a terrible idea
[tool.hatch.build.targets.sdist]
include = [ "/kalamine", "/layouts" ]

[project]
name = "kalamine"
version = "0.28"
Expand Down

0 comments on commit 5190f38

Please sign in to comment.