Files
climperor/web/loc_format.py
T
vosonandCursor 9c5aa5b610 Reorganize repository into pc web shared monorepo
Separate the local recognition, web publishing, and shared data paths while preserving direct script execution and existing site content.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-29 14:29:08 +08:00

99 lines
2.9 KiB
Python

"""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"<br\s*/?>", "\n", t, flags=re.I)
t = re.sub(r"</?h1[^>]*>", "\n", t, flags=re.I)
t = re.sub(r"</?font[^>]*>", "", 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_]+\}")