diff options
| author | Jules Aguillon | 2023-06-25 15:52:24 +0200 |
|---|---|---|
| committer | Jules Aguillon | 2023-06-25 15:52:24 +0200 |
| commit | 8ba82d2555342f6cf5e14d19c1d7bcadf46ab604 (patch) | |
| tree | 71495d1ab9cacbeffe8f8cf6abc069765ba2a54d /gen_layouts.py | |
| parent | f36864533c33f8f1986db150987e354c59c7482b (diff) | |
| download | unexpected-keyboard-8ba82d2555342f6cf5e14d19c1d7bcadf46ab604.tar.gz unexpected-keyboard-8ba82d2555342f6cf5e14d19c1d7bcadf46ab604.zip | |
Generate layouts arrays used in settings
`gen_layouts.py` lists the layouts in `res/xml` and generate the
`pref_layout_values` and `pref_layout_entries` arrays into
`res/values/layouts.xml`.
These arrays are hard to maintain as the order has to match, which is
fragile.
This relies on every layouts having a `name` attribute.
Diffstat (limited to 'gen_layouts.py')
| -rw-r--r-- | gen_layouts.py | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/gen_layouts.py b/gen_layouts.py new file mode 100644 index 0000000..2b86883 --- /dev/null +++ b/gen_layouts.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +# Generates the list of layouts in res/values/layouts.xml from the layout files +# in res/xml. Every layouts must have a 'name' attribute to be listed. + +import itertools as it +import sys, os, glob +import xml.etree.ElementTree as XML + +# Layouts first in the list (these are the programming layouts). Other layouts +# are sorted alphabetically. +FIRST_LAYOUTS = [ "latn_qwerty_us", "latn_colemak", "latn_dvorak" ] + +# Read a layout from a file. Returns [None] if [fname] is not a layout. +def read_layout(fname): + root = XML.parse(fname).getroot() + if root.tag != "keyboard": + return None + return { "name": root.get("name") } + +# Yields the id (based on the file name) and the display name for every layouts +def read_layouts(files): + for layout_file in files: + layout_id, _ = os.path.splitext(os.path.basename(layout_file)) + layout = read_layout(layout_file) + if layout == None: + print("Not a layout file: %s" % layout_file) + elif layout["name"] == None: + print("Layout doesn't have a name: %s" % layout_id) + else: + yield (layout_id, layout["name"]) + +# Sort layouts alphabetically, except for layouts in FIRST_LAYOUTS, which are +# placed at the top. +# Returns a list. 'layouts' can be an iterator. +def sort_layouts(layouts): + layouts = dict(layouts) + head = [ (lid, layouts.pop(lid)) for lid in FIRST_LAYOUTS ] + return head + sorted(layouts.items()) + +# Write the XML arrays used in the preferences. +def generate_arrays(out, layouts): + def add_items(parent, strings): + for s in strings: + item = XML.Element("item") + item.text = s + parent.append(item) + none_item = [ ("none", "None") ] + custom_item = [ ("custom", "@string/pref_layout_e_custom") ] + lids, names = zip(*(none_item + layouts + custom_item)) # unzip + values = XML.Element("string-array", name="pref_layout_values") + add_items(values, lids) + entries = XML.Element("string-array", name="pref_layout_entries") + add_items(entries, names) + root = XML.Element("resources") + root.append(XML.Comment(text="DO NOT EDIT. This file is generated, see gen_layouts.py.")) + root.append(values) + root.append(entries) + XML.indent(root) + XML.ElementTree(element=root).write(out, encoding="unicode", xml_declaration=True) + +layouts = sort_layouts(read_layouts(glob.glob("res/xml/*.xml"))) +with open("res/values/layouts.xml", "w") as out: + generate_arrays(out, layouts) |
