"""Generate Android colors.xml from design tokens.""" import json import os import xml.etree.ElementTree as ET from xml.dom import minidom _FILE_DIR = os.path.dirname(os.path.abspath(__file__)) ROOT = os.path.dirname(os.path.dirname(os.path.dirname(_FILE_DIR))) TOKENS_PATH = os.path.join(ROOT, "docs", "design-system", "tokens.json") OUTPUT_PATH = os.path.join(ROOT, "app", "design-tokens", "kotlin", "colors.xml") def load_tokens() -> dict: with open(TOKENS_PATH, encoding="utf-8-sig") as f: return json.load(f) def hex_to_argb(hex_color: str) -> str: h = hex_color.lstrip("#") if len(h) == 6: return f"FF{h}" return h def generate(tokens: dict) -> str: root = ET.Element("resources") for color_name, shades in tokens.get("colors", {}).items(): if isinstance(shades, dict): for shade, value in shades.items(): if shade not in ("system",) and isinstance(value, str) and value.startswith("#"): res_name = f"{color_name}_{shade}" argb = hex_to_argb(value) child = ET.SubElement(root, "color") child.set("name", res_name) child.text = f"#{argb}" for space_name, value in tokens.get("spacing", {}).items(): dp = value.replace("rem", "").strip() child = ET.SubElement(root, "dimen") child.set("name", f"spacing_{space_name}") child.text = f"{float(dp) * 16:.0f}dp" rough_string = ET.tostring(root, encoding="unicode") reparsed = minidom.parseString(rough_string) return '\n' + reparsed.toprettyxml(indent=" ") def main(): tokens = load_tokens() xml = generate(tokens) os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True) with open(OUTPUT_PATH, "w", encoding="utf-8") as f: f.write(xml) print(f"Written: {OUTPUT_PATH}") if __name__ == "__main__": main()