summaryrefslogtreecommitdiff
path: root/gerbonara/cad/kicad/tmtheme.py
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2023-07-22 14:25:18 +0200
committerjaseg <git@jaseg.de>2023-07-22 14:25:18 +0200
commitba4cafa3a43f3b6655e2cbfbc35d2505f0efccb1 (patch)
tree02a9314496f8a90d3e5a9d83fe86bbc2281c5c5f /gerbonara/cad/kicad/tmtheme.py
parent2f0a21abf937f97c4b1fd10a6574e53ddcd4d7cf (diff)
downloadgerbonara-ba4cafa3a43f3b6655e2cbfbc35d2505f0efccb1.tar.gz
gerbonara-ba4cafa3a43f3b6655e2cbfbc35d2505f0efccb1.tar.bz2
gerbonara-ba4cafa3a43f3b6655e2cbfbc35d2505f0efccb1.zip
Add tmtheme support
Diffstat (limited to 'gerbonara/cad/kicad/tmtheme.py')
-rw-r--r--gerbonara/cad/kicad/tmtheme.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/gerbonara/cad/kicad/tmtheme.py b/gerbonara/cad/kicad/tmtheme.py
new file mode 100644
index 0000000..52d9afd
--- /dev/null
+++ b/gerbonara/cad/kicad/tmtheme.py
@@ -0,0 +1,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()))
+