View-title text formatting#
Each view title has a French name line (index 0) and an English
subtitle line (index 1). Per the in-house template, all title lines use a
5 mm char height and the subtitle must be Italic and come from a
controlled vocabulary (FRONT VIEW, SECTION VIEW …). This demo checks
both lines for three drift dimensions — char_height, vocabulary, and
font_style — using each language’s view_type_patterns.
Input drawing#
Sheet 1 of support_assembly_wrong_view_names.json — three subtitles were
each corrupted along a different dimension: FRONT VIEW scaled ×1.5 (5→7.5
mm), SECTION VIEW → SECN VIEW (unknown vocabulary), and LEVELED
SECTION VIEW flipped italic → regular.
How the check works#
Check title lines 0 and 1 of every titled view against char height, the language’s standard view-name patterns, and (for the subtitle) font style.
"""Demo: View-title text formatting.
Checks each view's name (line 0) and English subtitle (line 1) against the
in-house template (5 mm char height, standard view-name vocabulary, italic
subtitle), then writes:
- ``view_names_report.md`` — Markdown formatting report (subtitle rows)
- ``view_names_check.html`` — annotated drawing (green=OK, red=FAIL)
Both are written into the current working directory.
"""
from pathlib import Path
from ..shared import write_report
from ..viz_helpers import load_sheet, render_html
from . import build_visualization
from .build_visualization import DRAWING_JSON, OUT_HTML
#: relative → written to the current working directory.
REPORT_MD = Path("view_names_report.md")
def _property_columns(check: "build_visualization.LineCheck") -> tuple[str, str, str]:
"""Return (property, expected, found) strings for the first problem, or dashes."""
if "char_height" in check.problems:
rendered_size = check.rendered_size
return "char_height", "5 mm", f"{rendered_size:g} mm" if rendered_size is not None else "?"
if "vocabulary" in check.problems:
return "text vocabulary", "standard english view name", check.text
if "font_style" in check.problems:
return "font_style", "Italic", check.font_style or "?"
return "—", "—", "—"
def subtitle_rows(checks: list["build_visualization.LineCheck"]) -> list["build_visualization.LineCheck"]:
"""One row per view's subtitle (line 1), collapsing duplicate texts.
Collapsing keys on ``(view_name, text)`` and keeps the first match — it assumes
same-text duplicate subtitles share the same formatting (true here: both
``LEVELED SECTION VIEW`` copies were flipped identically). If divergent
duplicates ever appear, key also on ``(check.ok, tuple(check.problems))`` so a
differing copy is not hidden.
"""
rows, seen = [], set()
for check in checks:
if check.line_idx != 1:
continue
key = (check.view_name, check.text)
if key in seen:
continue
seen.add(key)
rows.append(check)
return rows
def build_report_md(rows: list["build_visualization.LineCheck"]) -> str:
"""Render the Markdown subtitle table + summary for the formatting report."""
header = (
"| | View | Line | Text | Property | Expected | Found | Status |\n"
"|---|------|------|------|----------|----------|-------|--------|"
)
body_lines = []
for check in rows:
property_name, expected, found = _property_columns(check)
badge = "🟢" if check.ok else "🔴"
status = "OK" if check.ok else "FAIL"
body_lines.append(
f"| {badge} | {check.view_name} | 1 | {check.text} | {property_name} | {expected} | {found} | {status} |"
)
total = len(rows)
ok = sum(check.ok for check in rows)
rate = 100 * ok / total if total else 0.0
summary = (
f"**Summary (subtitles).** {total} subtitles checked · {ok} OK · " f"{total - ok} FAIL · pass rate {rate:.0f}%."
)
return "\n\n".join([header + "\n" + "\n".join(body_lines), summary])
def main() -> None:
"""Run the view-name formatting check, write the report and visualization."""
sheet = load_sheet(DRAWING_JSON, sheet_index=1)
checks = build_visualization.analyze(sheet)
for check in checks:
status = "OK" if check.ok else "FAIL"
detail = "" if check.ok else " : " + ", ".join(check.problems)
print(f"[{status}] {check.view_name!r} line[{check.line_idx}] {check.text!r}{detail}")
rows = subtitle_rows(checks)
write_report(REPORT_MD, "View-Title Formatting Check Report", [build_report_md(rows)])
render_html(sheet, build_visualization.build_extras(sheet), OUT_HTML)
if __name__ == "__main__":
main()
Result#
View |
Subtitle |
Property |
Expected |
Found |
Status |
|---|---|---|---|---|---|
VUE DE FACE |
FRONT VIEW |
char_height |
5 mm |
7.5 mm |
🔴 FAIL |
COUPE A2-A2 |
SECN VIEW |
text vocabulary |
standard name |
SECN VIEW |
🔴 FAIL |
COUPE B2-B2 |
SECTION VIEW |
— |
— |
— |
🟢 OK |
VUE ISOMETRIQUE |
ISOMETRIC VIEW |
— |
— |
— |
🟢 OK |
COUPE C2-C2 REDRESSEE |
LEVELED SECTION VIEW |
font_style |
Italic |
Regular |
🔴 FAIL |
5 subtitles · 2 OK · 3 FAIL · pass rate 40%. The visualization boxes each
mutated subtitle red with a label (Wrong text size / Unknown view name
/ Wrong text style) and every other title line green.