Created
April 19, 2023 18:26
-
-
Save drm00/7a07fab05afcf2429d03eae0cb643605 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# | |
# Script to transform the latest NEO2-layout for macos to a similar layout, | |
# such as KOY. It swaps the keycodes to the corresponding ones and leaves | |
# the rest of the file as it is. I use it to generate a KOY layout from | |
# the latest NEO2 upstream at | |
# | |
# https://git.neo-layout.org/neo/neo-layout/src/branch/master/mac_osx/neo-layouts.bundle/Contents/Resources/Deutsch%20%28Neo%202%29.keylayout | |
# | |
# Other layouts such as bone, mine etc. could be generated as well. | |
# Layers 4, 6, 8 and 9 are left untouched. | |
# | |
import re | |
import sys | |
neo2koy = { | |
'0': '5', | |
'5': '14', | |
'14': '31', | |
'31': '39', | |
'39': '17', | |
'17': '43', | |
'43': '15', | |
'15': '34', | |
'34': '32', | |
'32': '0', | |
'1': '3', | |
'3': '2', | |
'2': '1', | |
'4': '41', | |
'41': '4', | |
'6': '9', | |
'9': '46', | |
'46': '47', | |
'47': '13', | |
'13': '16', | |
'16': '12', | |
'12': '6', | |
'7': '11', | |
'11': '33', | |
'33': '35', | |
'35': '7', | |
'37': '38', | |
'38': '37', | |
} | |
def transform(input, output, target, debug=False): | |
layers = {} | |
current_layer = None | |
buffer = [] | |
with open(input) as f: | |
for n, line in enumerate(f): | |
original_line = line | |
line = line.strip() | |
if line.startswith('<keyboard group="'): | |
new_line = re.sub(r'Deutsch \(Neo 2\)', r'Deutsch (KOY)', original_line, count=1) | |
buffer.append(new_line) | |
continue | |
elif line.startswith('<keyMap index="'): | |
m = re.search(r'<keyMap index="(\d+)"', line) | |
if m: | |
layer = m.group(1) | |
if debug: print(f"layer {layer} starts at line {n}: {line}") | |
if layer in ['4', '6', '8', '9']: | |
# skip layers that should remain the same | |
if debug: print(f"leaving layer {layer} as it is") | |
else: | |
layers[layer] = {} | |
current_layer = layer | |
else: | |
print(f"ERROR: no layer index found at line {n}: {line}!", file=sys.stderr) | |
sys.exit(1) | |
buffer.append(original_line) | |
continue | |
elif line.startswith('</keyMap>'): | |
if current_layer is not None: | |
# write collected and modified keymaps for layer | |
s = sorted(layers[current_layer], key=int) | |
for i in s: | |
if debug: print(f"i: {i}, line: {layers[current_layer][i].strip()}") | |
buffer.append(layers[current_layer][i]) | |
buffer.append(original_line) | |
current_layer = None | |
continue | |
if current_layer is not None: | |
m = re.search(r'<key code="(\d+)"', line) | |
if m: | |
code = m.group(1) | |
else: | |
print(f"ERROR: no code found at line {n}: {line}!", file=sys.stderr) | |
sys.exit(1) | |
if code in target: | |
if debug: print(f"substituting code '{code}' to '{target[code]}' in line {n}: {line}") | |
new_line = re.sub(code, target[code], original_line, count=1) | |
if debug: print(f"result: {new_line.strip()}") | |
layers[current_layer][target[code]] = new_line | |
else: | |
layers[current_layer][code] = original_line | |
else: | |
buffer.append(original_line) | |
with open(output, 'w') as f: | |
f.writelines(buffer) | |
if __name__ == '__main__': | |
transform('Deutsch (Neo 2).keylayout', 'koy.keylayout', neo2koy, debug=False) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment