"""Shared Valve loc formatting: strip HTML and fill %token% / {s:token}.""" from __future__ import annotations import re from html import unescape def fmt_num(v: float) -> str: if abs(v - round(v)) < 1e-6: return str(int(round(v))) return f"{v:g}" def sv_lookup( special_values: list | None, prefer: str | None = None ) -> dict[str, list[float]]: """prefer: None | 'scepter' | 'shard' — choose values_* channel when present.""" out: dict[str, list[float]] = {} for sv in special_values or []: if not isinstance(sv, dict): continue name = str(sv.get("name") or "").strip() if not name: continue base = sv.get("values_float") or [] if not isinstance(base, list): base = [] sc = sv.get("values_scepter") or [] sh = sv.get("values_shard") or [] if not isinstance(sc, list): sc = [] if not isinstance(sh, list): sh = [] chosen = base if prefer == "scepter" and sc: chosen = sc elif prefer == "shard" and sh: chosen = sh out[name] = [float(x) for x in chosen if isinstance(x, (int, float))] if sc: out["scepter_" + name] = [ float(x) for x in sc if isinstance(x, (int, float)) ] if sh: out["shard_" + name] = [ float(x) for x in sh if isinstance(x, (int, float)) ] return out def strip_html(text: str) -> str: """Remove HTML tags and collapse whitespace (no token filling).""" if not text: return "" t = unescape(text) t = re.sub(r"", "\n", t, flags=re.I) t = re.sub(r"]*>", "\n", t, flags=re.I) t = re.sub(r"]*>", "", t, flags=re.I) t = re.sub(r"<[^>]+>", " ", t) return re.sub(r"[ \t]+", " ", t).strip() def format_loc( text: str, special_values: list | None = None, prefer: str | None = None, ) -> str: """Strip HTML and fill %token% / {s:token} from special_values when possible.""" if not text: return "" t = strip_html(text) t = re.sub(r"[ \t]+\n", "\n", t) lookup = sv_lookup(special_values or [], prefer=prefer) def repl_pct(m: re.Match) -> str: key = m.group(1) vals = lookup.get(key) if not vals and prefer: vals = lookup.get(f"{prefer}_{key}") if not vals: return "?" if len(vals) == 1: return fmt_num(vals[0]) if len(vals) <= 4: return " / ".join(fmt_num(v) for v in vals) return fmt_num(vals[0]) t = re.sub(r"%([A-Za-z0-9_]+)%", repl_pct, t) t = re.sub(r"\{s:([A-Za-z0-9_]+)\}", repl_pct, t) t = t.replace("%%", "%") t = re.sub(r"[ \t]+\n", "\n", t) t = re.sub(r"\n{3,}", "\n\n", t) t = re.sub(r"[ \t]{2,}", " ", t).strip() return t HAS_PLACEHOLDER = re.compile(r"%[A-Za-z0-9_]+%|\{s:[A-Za-z0-9_]+\}")