The entire parallel CSS system (StyleValue type, style dictionary, keyword atom resolver, content-addressed class generation, runtime CSS injection, localStorage caching) was built but never adopted — the codebase already uses :class strings with defcomp components for all styling. Remove ~3,000 lines of unused infrastructure. Deleted: - cssx.sx spec module (317 lines) - style_dict.py (782 lines) and style_resolver.py (254 lines) - StyleValue type, defkeyframes special form, build-keyframes platform fn - Style dict JSON delivery (<script type="text/sx-styles">), cookies, localStorage - css/merge-styles primitives, inject-style-value, fnv1a-hash platform interface Simplified: - defstyle now binds any value (string, function) — no StyleValue type needed - render-attrs no longer special-cases :style StyleValue → class conversion - Boot sequence skips style dict init step Preserved: - tw.css parsing + CSS class delivery (SX-Css headers, <style id="sx-css">) - All component infrastructure (defcomp, caching, bundling, deps) - defstyle as a binding form for reusable class strings Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
101 lines
3.1 KiB
Python
101 lines
3.1 KiB
Python
"""
|
|
Standard library primitives — isomorphic, opt-in modules.
|
|
|
|
Augment core with format, text, style, and debug primitives.
|
|
These are registered into the same _PRIMITIVES registry as core.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from .primitives import register_primitive
|
|
from .types import NIL
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# stdlib.format
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@register_primitive("format-date")
|
|
def prim_format_date(date_str: Any, fmt: str) -> str:
|
|
"""``(format-date date-str fmt)`` → formatted date string."""
|
|
from datetime import datetime
|
|
try:
|
|
dt = datetime.fromisoformat(str(date_str))
|
|
return dt.strftime(fmt)
|
|
except (ValueError, TypeError):
|
|
return str(date_str) if date_str else ""
|
|
|
|
|
|
@register_primitive("format-decimal")
|
|
def prim_format_decimal(val: Any, places: Any = 2) -> str:
|
|
"""``(format-decimal val places)`` → formatted decimal string."""
|
|
try:
|
|
return f"{float(val):.{int(places)}f}"
|
|
except (ValueError, TypeError):
|
|
return "0." + "0" * int(places)
|
|
|
|
|
|
@register_primitive("parse-int")
|
|
def prim_parse_int(val: Any, default: Any = 0) -> int | Any:
|
|
"""``(parse-int val default?)`` → int(val) with fallback."""
|
|
try:
|
|
return int(val)
|
|
except (ValueError, TypeError):
|
|
return default
|
|
|
|
|
|
@register_primitive("parse-datetime")
|
|
def prim_parse_datetime(val: Any) -> Any:
|
|
"""``(parse-datetime "2024-01-15T10:00:00")`` → ISO string or nil."""
|
|
from datetime import datetime
|
|
if not val or val is NIL:
|
|
return NIL
|
|
try:
|
|
dt = datetime.fromisoformat(str(val))
|
|
return dt.isoformat()
|
|
except (ValueError, TypeError):
|
|
return NIL
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# stdlib.text
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@register_primitive("pluralize")
|
|
def prim_pluralize(count: Any, singular: str = "", plural: str = "s") -> str:
|
|
"""``(pluralize count)`` → "s" if count != 1, else "".
|
|
``(pluralize count "item" "items")`` → "item" or "items"."""
|
|
try:
|
|
n = int(count)
|
|
except (ValueError, TypeError):
|
|
n = 0
|
|
if singular or plural != "s":
|
|
return singular if n == 1 else plural
|
|
return "" if n == 1 else "s"
|
|
|
|
|
|
@register_primitive("escape")
|
|
def prim_escape(s: Any) -> str:
|
|
"""``(escape val)`` → HTML-escaped string."""
|
|
from markupsafe import escape as _escape
|
|
return str(_escape(str(s) if s is not None and s is not NIL else ""))
|
|
|
|
|
|
@register_primitive("strip-tags")
|
|
def prim_strip_tags(s: str) -> str:
|
|
"""Strip HTML tags from a string."""
|
|
import re
|
|
return re.sub(r"<[^>]+>", "", s)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# stdlib.debug
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@register_primitive("assert")
|
|
def prim_assert(condition: Any, message: str = "Assertion failed") -> bool:
|
|
if not condition:
|
|
raise RuntimeError(f"Assertion error: {message}")
|
|
return True
|