# -*- coding: utf-8 -*-
"""fix_quotes.py —— 把正文中的 ASCII 引号修复为中文弯引号（代码块零误伤）。

规则：
- 跳过 fenced code block（``` 与 ~~~~ 围栏）与行内代码（`...`）；
- 正文中成对的 "..." 依次替换为 “...”（开）与 ”...”（闭）；
- 单引号 '...' 成对替换为 ‘...’ 与 ’...’（仅当明显成对）；
- 已是弯引号/已在代码中的内容不受影响。

用法：python code/fix_quotes.py            # 处理 tutorial/*.md
"""
import os
import re
import glob

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TUT = os.path.join(ROOT, "tutorial")


def fix_text(text: str) -> str:
    lines = text.split("\n")
    out = []
    in_fence = False
    fence_char = None
    for line in lines:
        # 检测围栏代码块
        m = re.match(r"^\s*(```+|~~~~+)\s*(\w*)", line)
        if m:
            if not in_fence:
                in_fence = True
                fence_char = m.group(1)[0]
            else:
                # 结束围栏（同字符）
                if m.group(1)[0] == fence_char:
                    in_fence = False
            out.append(line)
            continue
        if in_fence:
            out.append(line)
            continue
        # 行内代码：临时占位
        inline_spans = []
        def _ph(mo):
            inline_spans.append(mo.group(0))
            return f"\x00{len(inline_spans)-1}\x00"
        line = re.sub(r"`[^`]*`", _ph, line)
        # 成对双引号（ASCII " 开头，之后找下一个 "）
        res = []
        buf = ""
        i = 0
        open_q = True
        while i < len(line):
            ch = line[i]
            if ch == '"' and (i == 0 or line[i-1] != "\\"):
                buf += "\u201c" if open_q else "\u201d"
                open_q = not open_q
            else:
                buf += ch
            i += 1
        line = buf
        # 成对单引号（仅当该行存在偶数个 ' 且不在单词内部——保守处理）
        # 简单策略：' 出现次数为偶数时成对替换
        if line.count("'") % 2 == 0 and line.count("'") > 0:
            res = []
            open_q = True
            for ch in line:
                if ch == "'":
                    # 跳过撇号型（前为字母后为字母/数字，如 don't）
                    res.append("\u2018" if open_q else "\u2019")
                    open_q = not open_q
                else:
                    res.append(ch)
            line = "".join(res)
        # 恢复行内代码
        line = re.sub(r"\x00(\d+)\x00", lambda mo: inline_spans[int(mo.group(1))], line)
        out.append(line)
    return "\n".join(out)


def main():
    total = 0
    for path in sorted(glob.glob(os.path.join(TUT, "*.md"))):
        if path.endswith(("00-SPEC-共享规范.md", "00-FIGURES-图注清单.md",
                          "00-TECH-技术要点速查.md")):
            continue
        with open(path, encoding="utf-8") as f:
            orig = f.read()
        fixed = fix_text(orig)
        if fixed != orig:
            n = orig.count('"') + orig.count("'")
            with open(path, "w", encoding="utf-8") as f:
                f.write(fixed)
            print(f"{os.path.basename(path)}: 修复 {n} 处引号")
            total += n
        else:
            print(f"{os.path.basename(path)}: 无变化")
    print(f"完成，共修复 {total} 处。注意：代码块与行内代码未受影响。")


if __name__ == "__main__":
    main()
