feat: themes

This commit is contained in:
2026-04-01 10:45:02 +02:00
parent 0316e50233
commit 01a3e0095c
10 changed files with 413 additions and 66 deletions

View File

@@ -426,6 +426,11 @@ def _parse_line(keyword: str, args: list[str], line_num: int) -> IRNode:
content = " ".join([keyword] + args)
return Text(content=content, source_line=line_num)
elif keyword == "theme":
# theme "name" — sets the page theme (handled as _StyleDirective on Page)
theme_name = args[0] if args else "default"
return _ThemeDirective(theme_name, line_num)
elif keyword == "component":
# component name(arg1, arg2)
raw = " ".join(args)
@@ -450,6 +455,13 @@ def _parse_line(keyword: str, args: list[str], line_num: int) -> IRNode:
return ComponentUse(comp_name=keyword, args=args, source_line=line_num)
class _ThemeDirective(IRNode):
"""Temporary node — sets theme_name on the Page during tree building."""
def __init__(self, theme_name: str, line_num: int):
super().__init__(source_line=line_num)
self.theme_name = theme_name
class _UseDirective(IRNode):
"""Temporary node — triggers library loading during tree building."""
def __init__(self, lib_path: str, line_num: int):
@@ -756,12 +768,17 @@ def parse(source: str, components: dict[str, ComponentDef] | None = None) -> Pag
stack.pop()
if isinstance(node, _StyleDirective):
# Apply style directive to the current top of stack (parent)
if stack:
parent = stack[-1][1]
setattr(parent.style, node.attr, node.value)
continue
if isinstance(node, _ThemeDirective):
# Set theme on the root Page
if root and isinstance(root, Page):
root.theme_name = node.theme_name
continue
# Table children: columns and rows are absorbed by the Table node
if isinstance(node, _TableColumns):
if stack and isinstance(stack[-1][1], Table):