Events: 3861 → 21 lines, split into 8 sub-modules (renders, helpers, layouts, calendar, entries, slots, tickets, utils). Updated 16 bp routes. SX Docs: 3224 → 27 lines, split into 5 sub-modules (renders, utils, essays, helpers, layouts). Updated 37 import sites in bp/pages/routes.py. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
138 lines
5.3 KiB
Python
138 lines
5.3 KiB
Python
"""Shared utility functions for sx docs pages."""
|
|
from __future__ import annotations
|
|
|
|
from shared.sx.helpers import (
|
|
render_to_sx, SxExpr,
|
|
)
|
|
|
|
|
|
async def _nav_items_sx(items: list[tuple[str, str]], current: str | None = None) -> str:
|
|
"""Build nav link items as sx."""
|
|
parts = []
|
|
for label, href in items:
|
|
parts.append(await render_to_sx("nav-link",
|
|
href=href, label=label,
|
|
is_selected="true" if current == label else None,
|
|
select_colours="aria-selected:bg-violet-200 aria-selected:text-violet-900",
|
|
))
|
|
return "(<> " + " ".join(parts) + ")"
|
|
|
|
|
|
async def _doc_nav_sx(items: list[tuple[str, str]], current: str) -> str:
|
|
"""Build the in-page doc navigation pills."""
|
|
items_sx = " ".join(
|
|
f'(list "{label}" "{href}")'
|
|
for label, href in items
|
|
)
|
|
return await render_to_sx("doc-nav", items=SxExpr(f"(list {items_sx})"), current=current)
|
|
|
|
|
|
async def _attr_table_sx(title: str, attrs: list[tuple[str, str, bool]]) -> str:
|
|
"""Build an attribute reference table."""
|
|
from content.pages import ATTR_DETAILS
|
|
rows = []
|
|
for attr, desc, exists in attrs:
|
|
href = f"/reference/attributes/{attr}" if exists and attr in ATTR_DETAILS else None
|
|
rows.append(await render_to_sx("doc-attr-row", attr=attr, description=desc,
|
|
exists="true" if exists else None,
|
|
href=href))
|
|
return (
|
|
f'(div :class "space-y-3"'
|
|
f' (h3 :class "text-xl font-semibold text-stone-700" "{title}")'
|
|
f' (div :class "overflow-x-auto rounded border border-stone-200"'
|
|
f' (table :class "w-full text-left text-sm"'
|
|
f' (thead (tr :class "border-b border-stone-200 bg-stone-50"'
|
|
f' (th :class "px-3 py-2 font-medium text-stone-600" "Attribute")'
|
|
f' (th :class "px-3 py-2 font-medium text-stone-600" "Description")'
|
|
f' (th :class "px-3 py-2 font-medium text-stone-600 text-center w-20" "In sx?")))'
|
|
f' (tbody {" ".join(rows)}))))'
|
|
)
|
|
|
|
|
|
def _headers_table_sx(title: str, headers: list[tuple[str, str, str]]) -> str:
|
|
"""Build a headers reference table."""
|
|
rows = []
|
|
for name, value, desc in headers:
|
|
rows.append(
|
|
f'(tr :class "border-b border-stone-100"'
|
|
f' (td :class "px-3 py-2 font-mono text-sm text-violet-700 whitespace-nowrap" "{name}")'
|
|
f' (td :class "px-3 py-2 font-mono text-sm text-stone-500" "{value}")'
|
|
f' (td :class "px-3 py-2 text-stone-700 text-sm" "{desc}"))'
|
|
)
|
|
return (
|
|
f'(div :class "space-y-3"'
|
|
f' (h3 :class "text-xl font-semibold text-stone-700" "{title}")'
|
|
f' (div :class "overflow-x-auto rounded border border-stone-200"'
|
|
f' (table :class "w-full text-left text-sm"'
|
|
f' (thead (tr :class "border-b border-stone-200 bg-stone-50"'
|
|
f' (th :class "px-3 py-2 font-medium text-stone-600" "Header")'
|
|
f' (th :class "px-3 py-2 font-medium text-stone-600" "Value")'
|
|
f' (th :class "px-3 py-2 font-medium text-stone-600" "Description")))'
|
|
f' (tbody {" ".join(rows)}))))'
|
|
)
|
|
|
|
|
|
async def _primitives_section_sx() -> str:
|
|
"""Build the primitives section."""
|
|
from content.pages import PRIMITIVES
|
|
parts = []
|
|
for category, prims in PRIMITIVES.items():
|
|
prims_sx = " ".join(f'"{p}"' for p in prims)
|
|
parts.append(await render_to_sx("doc-primitives-table",
|
|
category=category,
|
|
primitives=SxExpr(f"(list {prims_sx})")))
|
|
return " ".join(parts)
|
|
|
|
|
|
async def _sx_header_sx(nav: str | None = None, *, child: str | None = None) -> str:
|
|
"""Build the sx docs menu-row."""
|
|
return await render_to_sx("menu-row-sx",
|
|
id="sx-row", level=1, colour="violet",
|
|
link_href="/", link_label="sx",
|
|
link_label_content=SxExpr('(span :class "font-mono" "(<x>)")'),
|
|
nav=SxExpr(nav) if nav else None,
|
|
child_id="sx-header-child",
|
|
child=SxExpr(child) if child else None,
|
|
)
|
|
|
|
|
|
async def _docs_nav_sx(current: str | None = None) -> str:
|
|
from content.pages import DOCS_NAV
|
|
return await _nav_items_sx(DOCS_NAV, current)
|
|
|
|
|
|
async def _reference_nav_sx(current: str | None = None) -> str:
|
|
from content.pages import REFERENCE_NAV
|
|
return await _nav_items_sx(REFERENCE_NAV, current)
|
|
|
|
|
|
async def _protocols_nav_sx(current: str | None = None) -> str:
|
|
from content.pages import PROTOCOLS_NAV
|
|
return await _nav_items_sx(PROTOCOLS_NAV, current)
|
|
|
|
|
|
async def _examples_nav_sx(current: str | None = None) -> str:
|
|
from content.pages import EXAMPLES_NAV
|
|
return await _nav_items_sx(EXAMPLES_NAV, current)
|
|
|
|
|
|
async def _essays_nav_sx(current: str | None = None) -> str:
|
|
from content.pages import ESSAYS_NAV
|
|
return await _nav_items_sx(ESSAYS_NAV, current)
|
|
|
|
|
|
async def _main_nav_sx(current_section: str | None = None) -> str:
|
|
from content.pages import MAIN_NAV
|
|
return await _nav_items_sx(MAIN_NAV, current_section)
|
|
|
|
|
|
async def _sub_row_sx(sub_label: str, sub_href: str, sub_nav: str,
|
|
selected: str = "") -> str:
|
|
"""Build the level-2 sub-section menu-row."""
|
|
return await render_to_sx("menu-row-sx",
|
|
id="sx-sub-row", level=2, colour="violet",
|
|
link_href=sub_href, link_label=sub_label,
|
|
selected=selected or None,
|
|
nav=SxExpr(sub_nav),
|
|
)
|