fix: align hue budget with supertensor — per-row instead if figure-wide

Adopt per-row ≤4 active hue families, matching supertensor's documented
behavior. Also changed tests/lint-invalid/hue-budget.tex to use \sfrow
so the per-row rule actually triggers.
This commit is contained in:
dela
2026-08-22 10:14:32 +08:00
parent 6ed01743cf
commit 05f50b0a94
2 changed files with 18 additions and 14 deletions
+11 -9
View File
@@ -19,6 +19,7 @@ ROLE_KEY_RE = re.compile(r"role\s*=\s*([A-Za-z0-9_-]+)")
RAW_TIKZ_RE = re.compile(r"\\(?:draw|fill|path)\b")
ROW_NAME_RE = re.compile(r"\\sfrow\{([^{}]+)\}")
CALLOUT_RE = re.compile(r"\\sfcallout\{([^{}]+)\}\{[^{}]+\}\{([^{}]+)\}")
ROW_RE = re.compile(r"\\sfrow\{[^{}]+\}\{[^{}]+\}(.*?)\\sfrowend", re.DOTALL)
GROUP_RE = re.compile(
r"\\sfgroup(?:\[[^\]]*\])?\{([^{}]+)\}\{([^{}]*)\}\{([^{}]*)\}"
)
@@ -57,7 +58,6 @@ def lint(path: Path) -> list[str]:
else:
declared[name] = color
used_colors = {"sfGray"}
for match in ROLE_KEY_RE.finditer(source):
role = match.group(1)
color = declared.get(role)
@@ -66,15 +66,17 @@ def lint(path: Path) -> list[str]:
f"line {line_of(source, match.start())}: role {role!r} is used "
f"before \\sfsetrole"
)
else:
used_colors.add(color)
active = used_colors - {"sfGray"}
if len(active) > 4:
errors.append(
f"figure uses {len(active)} active hue families "
f"({', '.join(sorted(active))}); maximum is 4 plus gray"
)
for row_number, row in enumerate(ROW_RE.finditer(source), start=1):
row_roles = set(ROLE_KEY_RE.findall(row.group(1)))
colors = {declared.get(role, "<undeclared>") for role in row_roles}
active = colors - {"sfGray"}
if len(active) > 4:
errors.append(
f"line {line_of(source, row.start())}: row {row_number} uses "
f"{len(active)} active hue families "
f"({', '.join(sorted(active))}); maximum is 4 plus gray"
)
if "allow-raw-tikz" not in allowed:
for match in RAW_TIKZ_RE.finditer(source):