summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lulua/keyboard.py70
-rw-r--r--lulua/render.py36
2 files changed, 106 insertions, 0 deletions
diff --git a/lulua/keyboard.py b/lulua/keyboard.py
index 8fb7913..bd1d449 100644
--- a/lulua/keyboard.py
+++ b/lulua/keyboard.py
@@ -91,6 +91,72 @@ _buttonToXorgKeycode = {
'Fr_ctrl': 105,
}
+_buttonToKeyman = {
+ 'Bl1': 'K_BKSLASH',
+ 'Bl2': 'K_1',
+ 'Bl3': 'K_2',
+ 'Bl4': 'K_3',
+ 'Bl5': 'K_4',
+ 'Bl6': 'K_5',
+ 'Bl7': 'K_6',
+ 'Br6': 'K_7',
+ 'Br5': 'K_8',
+ 'Br4': 'K_9',
+ 'Br3': 'K_0',
+ 'Br2': 'K_LBRKT',
+ 'Br1': 'K_RBRKT',
+ 'Br_bs': 'K_BKSP',
+ 'Cl_tab': 'K_TAB',
+ 'Cl1': 'K_Q',
+ 'Cl2': 'K_W',
+ 'Cl3': 'K_E',
+ 'Cl4': 'K_R',
+ 'Cl5': 'K_T',
+ 'Cr7': 'K_Z',
+ 'Cr6': 'K_U',
+ 'Cr5': 'K_I',
+ 'Cr4': 'K_O',
+ 'Cr3': 'K_P',
+ 'Cr2': 'K_COLON',
+ 'Cr1': 'K_EQUAL',
+ 'CD_ret': 'K_ENTER',
+ 'Dl_caps': 'CAPS',
+ 'Dl1': 'K_A',
+ 'Dl2': 'K_S',
+ 'Dl3': 'K_D',
+ 'Dl4': 'K_F',
+ 'Dl5': 'K_G',
+ 'Dr7': 'K_H',
+ 'Dr6': 'K_J',
+ 'Dr5': 'K_K',
+ 'Dr4': 'K_L',
+ 'Dr3': 'K_BKQUOTE',
+ 'Dr2': 'K_QUOTE',
+ 'Dr1': 'K_SLASH',
+ 'El_shift': 'SHIFT', # XXX: there is no distinction between left/right
+ 'El1': 'K_oE2',
+ 'El2': 'K_Y',
+ 'El3': 'K_X',
+ 'El4': 'K_C',
+ 'El5': 'K_V',
+ 'El6': 'K_B',
+ 'Er5': 'K_N',
+ 'Er4': 'K_M',
+ 'Er3': 'K_COMMA',
+ 'Er2': 'K_PERIOD',
+ 'Er1': 'K_HYPHEN',
+ 'Er_shift': 'SHIFT',
+ 'Fl_ctrl': 'LCTRL',
+ 'Fl_win': 'K_?5B',
+ 'Fl_alt': 'LALT',
+ 'Fl_space': 'K_SPACE',
+ 'Fr_space': 'K_SPACE',
+ 'Fr_altgr': 'RALT',
+ 'Fr_win': 'K_?5C',
+ 'Fr_menu': 'K_?5D',
+ 'Fr_ctrl': 'RCTRL',
+ }
+
class Button:
__slots__ = ('width', 'isMarked', 'i')
_idToName : Dict[int, Text] = {}
@@ -129,6 +195,10 @@ class Button:
def xorgKeycode (self):
return _buttonToXorgKeycode[self.name]
+ @property
+ def keymanCode (self):
+ return _buttonToKeyman[self.name]
+
@classmethod
def deserialize (self, data: Dict):
kindMap = {'standard': Button, 'letter': LetterButton, 'multi': MultiRowButton}
diff --git a/lulua/render.py b/lulua/render.py
index 9aa7204..dce8961 100644
--- a/lulua/render.py
+++ b/lulua/render.py
@@ -325,6 +325,40 @@ def renderXmodmap (args):
fd.write (f'!! {btn.name}\nkeycode {btn.xorgKeycode} = {v}\n')
fd.write ('\n'.join (['add Mod3 = ISO_First_Group', 'add Mod5 = ISO_Level3_Shift', '']))
+def renderKeyman (args):
+ """ Rudimentary keyman script generation. Note that keyman is somewhat
+ unflexible when it comes to shift states and therefore layouts with
+ non-standard shift keys/states won’t work. """
+
+ keyboard = defaultKeyboards[args.keyboard]
+ layout = defaultLayouts[args.layout].specialize (keyboard)
+
+ with open (args.output, 'w') as fd:
+ fd.write ('\n'.join ([
+ 'c Auto-generated file for Keyman 11.0',
+ f'c layout: {layout.name}',
+ f'c generated: {datetime.utcnow ()}',
+ '',
+ 'store(&version) "9.0"',
+ f'store(&name) "{layout.name}"',
+ 'store(&mnemoniclayout) "0"',
+ 'store(&targets) "any"',
+ '',
+ 'begin Unicode > use(main)',
+ 'group(main) using keys',
+ '',
+ ]))
+ for i, l in enumerate (layout.layers):
+ for m in l.modifier:
+ for x in m:
+ if x.keymanCode.startswith ('K_') or x.keymanCode == 'CAPS':
+ logging.error (f'Keyman does not support custom modifier like {m}. Your layout will not work correctly.')
+ break
+ for btn, text in l.layout.items ():
+ comb = ' '.join ([x.keymanCode for x in m] + [btn.keymanCode])
+ text = ' '.join ([f'U+{ord (x):04X}' for x in text])
+ fd.write (f'+ [{comb}] > {text}\n')
+
def render ():
parser = argparse.ArgumentParser(description='Render keyboard into output format.')
parser.add_argument('-l', '--layout', metavar='LAYOUT', help='Keyboard layout name')
@@ -335,6 +369,8 @@ def render ():
sp.set_defaults (func=renderSvg)
sp = subparsers.add_parser('xmodmap')
sp.set_defaults (func=renderXmodmap)
+ sp = subparsers.add_parser('keyman')
+ sp.set_defaults (func=renderKeyman)
parser.add_argument('output', metavar='FILE', help='Output file')
logging.basicConfig (level=logging.INFO)