(layout)
| 72 | return root, keys, dup |
| 73 | |
| 74 | def check_layout(layout): |
| 75 | root, keys, dup = layout |
| 76 | if len(dup) > 0: warn("Duplicate keys: " + key_list_str(dup)) |
| 77 | missing_some_of(keys, "~!@#$%^&*(){}`[]=\\-_;:/.,?<>'\"+|", "ASCII punctuation") |
| 78 | missing_some_of(keys, "0123456789", "digits") |
| 79 | missing_required(keys, ["backspace", "delete"], "Layout doesn't define some important keys") |
| 80 | unexpected_keys(keys, |
| 81 | ["copy", "paste", "cut", "selectAll", "shareText", |
| 82 | "pasteAsPlainText", "undo", "redo" ], |
| 83 | "Layout contains editing keys") |
| 84 | unexpected_keys(keys, |
| 85 | [ "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", |
| 86 | "f10", "f11", "f12" ], |
| 87 | "Layout contains function keys") |
| 88 | unexpected_keys(keys, [""], "Layout contains empty strings") |
| 89 | unexpected_keys(keys, ["loc"], "Special keyword cannot be a symbol") |
| 90 | unexpected_keys(keys, filter(lambda k: k.strip()!=k, keys), "Some keys contain whitespaces") |
| 91 | unexpected_keys(keys, ["f11_placeholder", "f12_placeholder"], "These keys are now added automatically") |
| 92 | |
| 93 | if root.get("script", "latin") == "latin": |
| 94 | missing_required(keys, ["shift", "loc capslock"], "Missing important key") |
| 95 | missing_required(keys, ["loc esc", "loc tab"], "Missing programming keys") |
| 96 | |
| 97 | _, bottom_row_keys, _ = parse_row("res/xml/bottom_row.xml") |
| 98 | |
| 99 | if root.get("bottom_row") == "false": |
| 100 | missing_required(keys, bottom_row_keys, |
| 101 | "Layout redefines the bottom row but some important keys are missing") |
| 102 | else: |
| 103 | unexpected_keys(keys, bottom_row_keys, |
| 104 | "Layout contains keys present in the bottom row") |
| 105 | |
| 106 | if root.get("script") == None: |
| 107 | warn("Layout doesn't specify a script.") |
| 108 | |
| 109 | keys_without_loc = set(( k.removeprefix("loc ") for k in keys )) |
| 110 | # Keys with a len under 3 are often composed characters |
| 111 | special_keys = set(( k for k in keys_without_loc if len(k) > 3 and ":" not in k )) |
| 112 | unknown = special_keys.difference(known_keys) |
| 113 | if len(unknown) > 0: |
| 114 | warn("Layout contains unknown keys: %s" % key_list_str(unknown)) |
| 115 | |
| 116 | # Fill 'known_keys', which is used for some checks |
| 117 | def parse_known_keys(): |
no test coverage detected