61 lines
1.9 KiB
Python
61 lines
1.9 KiB
Python
"""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 '<?xml version="1.0" encoding="utf-8"?>\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()
|