if we have a VS Code URL
def render_location(with_colon: bool = False):
location_parts = (
(frinfo["location"], lineno) if lineno else (frinfo["location"],)
)
if with_colon:
location_parts = (*location_parts, colon)
if vscode_url:
doc.a(*location_parts, href=vscode_url, class_="frame-location")
else:
doc.span(*location_parts, class_="frame-location")
if toggle_id:
# Wrap both location and function in a label for click-to-toggle
with doc.label(for_=toggle_id, class_="frame-label-wrapper"):
if function_display:
render_location()
doc.span(function_display, colon, class_="frame-function")
else:
# No function: colon goes with location, empty span for grid column 2
render_location(with_colon=True)
doc.span(class_="frame-function")
else:
if function_display:
render_location()
doc.span(function_display, colon, class_="frame-function")
else:
# No function: colon goes with location, empty span for grid column 2
render_location(with_colon=True)
doc.span(class_="frame-function")
def _render_fragment(doc: Any, fragment: dict[str, Any]) -> None:
"""Render a single fragment with appropriate styling."""
code = fragment["code"]
mark = fragment.get("mark")
em = fragment.get("em")
# Render opening tags for "mark" and "em" if applicable
if mark in ["solo", "beg"]:
doc(HTML(""))
if em in ["solo", "beg"]:
doc(HTML(""))
# Render the code
doc(code)
# Render closing tags for "mark" and "em" if applicable
if em in ["fin", "solo"]:
doc(HTML(""))
if mark in ["fin", "solo"]:
doc(HTML(""))
def variable_inspector(doc: Any, variables: list[Any]) -> None:
if not variables:
return
with doc.dl(class_="inspector"):
for var_info in variables:
# Handle both old tuple format and new VarInfo namedtuple
if hasattr(var_info, "name"):
n, t, v, fmt = (
var_info.name,
var_info.typename,
var_info.value,
var_info.format_hint,
)
else:
# Backwards compatibility with old tuple format
n, t, v = var_info
fmt = "inline"
doc.dt.span(n, class_="var")
if t:
doc(": ").span(f"{t}\u00a0=\u00a0", class_="type")
else:
doc("\u00a0").span("=\u00a0", class_="type") # No type printed
doc.dd(class_=f"val val-{fmt}")
if isinstance(v, str):
if fmt == "block":
# For block format, use tag for proper formatting
doc.pre(v)
else:
doc(v)
elif isinstance(v, dict) and v.get("type") == "keyvalue":
_format_keyvalue(doc, v["rows"])
elif isinstance(v, dict) and v.get("type") == "array":
with doc.div(class_="array-with-scale"):
_format_matrix(doc, v["rows"])
if v.get("suffix"):
doc.span(v["suffix"], class_="scale-suffix")
else:
_format_matrix(doc, v)
def _format_keyvalue(doc: Any, rows: list[tuple[str, Any]]) -> None:
"""Format key-value pairs (dicts, dataclasses) as a definition list."""
with doc.dl(class_="keyvalue-dl"):
for key, val in rows:
doc.dt(key)
doc.dd(val)
def _format_matrix(doc: Any, v: Any) -> None:
skipcol = skiprow = False
with doc.table:
for row in v:
if row[0] is None:
skiprow = True
continue
doc.tr()
if skiprow:
skiprow = False
doc(class_="skippedabove")
for e in row:
if e is None:
skipcol = True
continue
if skipcol:
skipcol = False
doc.td(e, class_="skippedleft")
else:
doc.td(e)