summaryrefslogtreecommitdiff
path: root/gerbonara/cad/kicad/tmtheme.py
blob: 52d9afdec53c6133107638136bcf95e4ada7fe12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from xml.etree import ElementTree
import base64
from pathlib import Path

def _map_primitive(element):
    match element.tag:
        case 'data':
            return base64.b64decode(element.text)
        case 'date':
            return element.text
        case 'true':
            return True
        case 'false':
            return False
        case 'real':
            return float(element.text)
        case 'integer':
            return int(element.text)
        case 'string':
            return element.text
        case 'array':
            return [_map_primitive(child) for child in element]
        case 'dict':
            children = list(element)
            return {k.text: _map_primitive(v) for k, v in zip(children[0::2], children[1::2])}


def parse_shitty_json(data):
    # Parse apple plist XML
    root = ElementTree.fromstring(data)
    return _map_primitive(root[0])

class TmThemeSchematic:
    def __init__(self, data):
        self.theme = parse_shitty_json(data)
        s = self.theme['settings'][0]['settings']
        by_scope = {}
        for elem in self.theme['settings']:
            if 'scope' not in elem:
                continue
            for scope in elem['scope'].split(','):
                by_scope[scope.strip()] = elem.get('settings', {})

        def lookup(default, *scopes):
            for scope in scopes:
                if not (elem := by_scope.get(scope)):
                    continue

                if 'foreground' not in elem:
                    continue

                return elem['foreground']
            return default

        self.background = s.get('background', 'white')
        self.bus = lookup('black', 'constant.other', 'storage.type')
        self.wire = self.lines = lookup('black', 'constant.other')
        self.no_connect = lookup('black', 'constant.language', 'variable')
        self.text = lookup('black', 'constant.numeric', 'constant.numeric.hex', 'storage.type.number')
        self.pin_numbers = lookup('black', 'constant.character', 'constant.other')
        self.pin_names = lookup('black', 'constant.character.format.placeholder', 'constant.other.placeholder')
        self.values = lookup('black', 'constant.character.format.placeholder', 'constant.other.placeholder')
        self.labels = lookup('black', 'constant.numeric', 'constant.numeric.hex', 'storage.type.number')
        self.fill = s.get('background')
        print(f'{self.background=} {self.wire=} {self.bus=} {self.lines=} {self.no_connect=} {self.labels=} {self.fill=}')

if __name__ == '__main__':
    print(parse_shitty_json(Path('/tmp/witchhazelhypercolor.tmTheme').read_text()))