#!/usr/bin/env python3 """Lint TSL codegen API Markdown against the house standard. The standard lives in tools/tsl-codegen/STANDARD.md. Each typed H2 starts one top-level declaration; typed H3/H4 headings describe class or unit members. Rules split into hard errors (CI-blocking) and soft warnings (style convergence over the ~12k existing entries). Hard errors include incomplete descriptions/metadata/parameter tables and invalid class/unit API headings, visibility, or child-heading levels. Soft warnings: - optional-parameter wording not starting with `可选。` - malformed / empty `` line Exit status: 1 if any error (or, with --strict, any warning); else 0. Usage: python lint.py --file path/to/page.md python lint.py --dir path/to/codegen-dir python lint.py --dir path/to/codegen-dir --strict """ import argparse import re import sys from pathlib import Path SCRIPT_DIR = Path(__file__).resolve().parent if str(SCRIPT_DIR) not in sys.path: sys.path.insert(0, str(SCRIPT_DIR)) from api_markdown import DECLARATION_LINE_RE, iter_api_entries RETURN_LINE_RE = re.compile(r"^返回[::]") RETURN_RE = re.compile(r"^返回[::]\s*\S") TYPE_LINE_RE = re.compile(r"^类型[::]\s*(.*?)\s*$", re.IGNORECASE) TYPE_RE = re.compile(r"^类型[::]\s*\S") VALUE_LINE_RE = re.compile(r"^值[::]") VALUE_RE = re.compile(r"^值[::]\s*(?:`[^`]+`|[^`\s])") ACCESS_RE = re.compile(r"^访问[::]\s*(read|write|read\s*/\s*write)\s*$") VISIBILITY_RE = re.compile(r"^可见性[::]\s*`?(public|protected|private)`?\s*$") BASE_RE = re.compile(r"^父类[::]") MODIFIERS_RE = re.compile(r"^修饰符[::]") TAGS_RE = re.compile(r"^\s*$") FENCE_RE = re.compile(r"^(```|~~~)") HEADING_RE = re.compile(r"^(#{1,6})(?!#)\s+(.+?)\s*$") VALUE_HEADING_RE = re.compile(r"^`.+?`\s+取值$") OPTIONAL_HINT_RE = re.compile(r"可选|可省略|省略") # Split a table row on unescaped pipes so `nil\|array` stays one cell. CELL_SPLIT_RE = re.compile(r"(?