diff --git a/convert_cldr.py b/convert_cldr.py new file mode 100755 index 000000000..59d699eda --- /dev/null +++ b/convert_cldr.py @@ -0,0 +1,111 @@ +#!/usr/bin/python + +from gi.repository import Gdk +from xml.etree.ElementTree import ElementTree, Element +import re + +ESCAPE_PATTERN = re.compile(r'\\u\{([0-9A-Fa-f]+?)\}') +ISO_PATTERN = re.compile(r'[A-E]([0-9]+)') + + +def parse_single_key(value): + key = Element('key') + uc = 0 + if hasattr(__builtins__, 'unichr'): + def unescape(m): + return chr(int(m.group(1), 16)) + else: + def unescape(m): + return chr(int(m.group(1), 16)) + value = ESCAPE_PATTERN.sub(unescape, value) + if len(value) > 1: + key.set('text', value) + uc = ord(value[0]) + keyval = Gdk.unicode_to_keyval(uc) + name = Gdk.keyval_name(keyval) + key.set('name', name) + return key + + +def convert(source, tree): + root = Element('layout') + for index, keymap in enumerate(tree.iter('keyMap')): + level = Element('level') + rows = {} + root.append(level) + level.set('name', 'level%d' % (index+1)) + # FIXME: heuristics here + modifiers = keymap.get('modifiers') + if not modifiers: + mode = 'default' + elif 'shift' in modifiers.split(' ') or 'lock' in modifiers.split(' '): + mode = 'latched' + else: + mode = 'locked' + level.set('mode', mode) + for _map in keymap.iter('map'): + value = _map.get('to') + key = parse_single_key(value) + iso = _map.get('iso') + if not ISO_PATTERN.match(iso): + sys.stderr.write('invalid ISO key name: %s\n' % iso) + continue + if not iso[0] in rows: + rows[iso[0]] = [] + rows[iso[0]].append((int(iso[1:]), key)) + # add attribute to certain keys + name = key.get('name') + if name == 'space': + key.set('align', 'center') + key.set('width', '6.0') + if name in ('space', 'BackSpace'): + key.set('repeatable', 'yes') + # add subkeys + longPress = _map.get('longPress') + if longPress: + for value in longPress.split(' '): + subkey = parse_single_key(value) + key.append(subkey) + for k, v in sorted(list(rows.items()), key=lambda x: x[0], reverse=True): + row = Element('row') + for key in sorted(v, key=lambda x: x): + row.append(key[1]) + level.append(row) + return root + + +def indent(elem, level=0): + i = "\n" + level*" " + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = i + " " + if not elem.tail or not elem.tail.strip(): + elem.tail = i + for elem in elem: + indent(elem, level+1) + if not elem.tail or not elem.tail.strip(): + elem.tail = i + else: + if level and (not elem.tail or not elem.tail.strip()): + elem.tail = i + +if __name__ == "__main__": + import sys + + if len(sys.argv) != 2: + print("supply a CLDR keyboard file") + sys.exit(1) + + source = sys.argv[-1] + itree = ElementTree() + itree.parse(source) + + root = convert(source, itree) + indent(root) + + otree = ElementTree(root) + if hasattr(sys.stdout, 'buffer'): + out = sys.stdout.buffer + else: + out = sys.stdout + otree.write(out, xml_declaration=True, encoding='UTF-8')