[caribou] tools: Add converter from CLDR keyboard data



commit 661175c3f49d7857aa6c29e43d88766553f39c60
Author: Daiki Ueno <dueno src gnome org>
Date:   Sat Jan 17 11:28:50 2015 +0900

    tools: Add converter from CLDR keyboard data
    
    The convert_cldr.py script reads a CLDR keyboard data and produces a
    Caribou layout file.  It can be used as:
    
      ./tools/convert_cldr.py fr-t-k0-android-qwertz.xml > fr.xml
    
    For simplicity, the script adds only the keys defined in the input
    file.  To make the generated layout really useful, you will need to
    add 'Caribou_ShiftUp' etc.

 tools/Makefile.am     |    1 +
 tools/convert_cldr.py |  111 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 112 insertions(+), 0 deletions(-)
---
diff --git a/tools/Makefile.am b/tools/Makefile.am
index ba84708..3a9bcdb 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,6 +1,7 @@
 EXTRA_DIST = \
        fix_gir.py \
        make_schema.py \
+       convert_cldr.py \
        basic.xsl
 
 -include $(top_srcdir)/git.mk
diff --git a/tools/convert_cldr.py b/tools/convert_cldr.py
new file mode 100755
index 0000000..cd65754
--- /dev/null
+++ b/tools/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 unichr(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(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')


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]