diff --git a/scripts/lint.py b/scripts/lint.py index 63b0a24..0103cbd 100755 --- a/scripts/lint.py +++ b/scripts/lint.py @@ -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, "") 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): diff --git a/tests/lint-invalid/hue-budget.tex b/tests/lint-invalid/hue-budget.tex index 544d7b0..5c14b29 100644 --- a/tests/lint-invalid/hue-budget.tex +++ b/tests/lint-invalid/hue-budget.tex @@ -6,9 +6,11 @@ \sfsetrole{d}{sfViolet} \sfsetrole{e}{sfInk} \begin{document}\begin{tikzpicture} -\sfnode[role=a, at={(0,0)}]{A}{A}{8mm}{8mm} -\sfnode[role=b, at={(12mm,0)}]{B}{B}{8mm}{8mm} -\sfnode[role=c, at={(24mm,0)}]{C}{C}{8mm}{8mm} -\sfnode[role=d, at={(36mm,0)}]{D}{D}{8mm}{8mm} -\sfnode[role=e, at={(48mm,0)}]{E}{E}{8mm}{8mm} +\sfrow{R1}{14mm} + \sfnode[role=a]{A}{A}{8mm}{8mm} + \sfnode[role=b]{B}{B}{8mm}{8mm} + \sfnode[role=c]{C}{C}{8mm}{8mm} + \sfnode[role=d]{D}{D}{8mm}{8mm} + \sfnode[role=e]{E}{E}{8mm}{8mm} +\sfrowend \end{tikzpicture}\end{document}