diff options
Diffstat (limited to '.ai/scripts/cj-scan.py')
| -rw-r--r-- | .ai/scripts/cj-scan.py | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/.ai/scripts/cj-scan.py b/.ai/scripts/cj-scan.py index 54e2bf9..275f5ca 100644 --- a/.ai/scripts/cj-scan.py +++ b/.ai/scripts/cj-scan.py @@ -30,6 +30,7 @@ VALID_VERIFY_DEPTHS = {2, 3} HEADING_RE = re.compile(r"^(\*+)\s+(.*)$") SRC_OPEN_RE = re.compile(r"^\s*#\+begin_src\s+cj:\s*(\S*)\s*$", re.IGNORECASE) SRC_CLOSE_RE = re.compile(r"^\s*#\+end_src\s*$", re.IGNORECASE) +BLOCK_OPEN_RE = re.compile(r"^\s*#\+begin_(\w+)(?:\s.*)?$", re.IGNORECASE) LEGACY_CJ_RE = re.compile(r"^\s*cj:\s*(.*)$") VERIFY_KEYWORD_RE = re.compile(r"^VERIFY(\s|\[|$)") @@ -66,6 +67,13 @@ def scan_file(path: Path) -> dict[str, object]: block_label: str | None = None block_body: list[str] = [] + # Tracks a non-cj `#+begin_<type>` wrapper currently in scope. Inside a + # wrapper, cj fence patterns are *content* (documentation examples, + # quoted prose, snippet definitions) -- not annotations -- so we + # suppress matching until the wrapper closes. The closer is type-keyed: + # `#+end_example` for example, `#+end_src` for src, etc. + wrapper_type: str | None = None + file_str = str(path) lines = path.read_text().splitlines() @@ -90,6 +98,15 @@ def scan_file(path: Path) -> dict[str, object]: block_body.append(line) continue + if wrapper_type is not None: + wrapper_close_re = re.compile( + rf"^\s*#\+end_{re.escape(wrapper_type)}\s*$", + re.IGNORECASE, + ) + if wrapper_close_re.match(line): + wrapper_type = None + continue + m_heading = HEADING_RE.match(line) if m_heading: depth = len(m_heading.group(1)) @@ -110,6 +127,9 @@ def scan_file(path: Path) -> dict[str, object]: }) continue + # cj-open must be checked before the generic begin-block match: a + # `#+begin_src cj: ...` line matches both patterns, and cj-open is + # the more specific intent. m_src_open = SRC_OPEN_RE.match(line) if m_src_open: in_cj_block = True @@ -118,6 +138,11 @@ def scan_file(path: Path) -> dict[str, object]: block_body = [] continue + m_block_open = BLOCK_OPEN_RE.match(line) + if m_block_open: + wrapper_type = m_block_open.group(1).lower() + continue + m_legacy = LEGACY_CJ_RE.match(line) if m_legacy: cj_blocks.append({ |
