#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 把 docs/md_cursor/作业3_追踪Agent工具调用验收_cursor.md 转成“可直接打开的 HTML”。 不依赖第三方 markdown 库(当前环境未安装 markdown/mistune)。 """ from __future__ import annotations import html import re from pathlib import Path def inline_format(text: str) -> str: """ text 先做了 escape,这里只做少量 inline markdown -> html: - **bold** - `inline code` """ # **bold** text = re.sub(r"\*\*(.+?)\*\*", r"\1", text) # `code` text = re.sub(r"`(.+?)`", r"\1", text) return text def md_to_html(md: str) -> str: md = md.replace("\r\n", "\n") lines = md.split("\n") out: list[str] = [] para: list[str] = [] in_code = False code_lang = "" code_buf: list[str] = [] def flush_para(): nonlocal para if not para: return text = " ".join(x.strip() for x in para if x.strip()) if text: out.append(f"

{inline_format(html.escape(text))}

") para = [] def flush_ul(items: list[str]): if not items: return lis = "".join(f"
  • {inline_format(html.escape(it))}
  • " for it in items) out.append(f"") def flush_ol(items: list[str]): if not items: return lis = "".join(f"
  • {inline_format(html.escape(it))}
  • " for it in items) out.append(f"
      {lis}
    ") i = 0 while i < len(lines): line = lines[i] # code fence if line.strip().startswith("```"): if not in_code: flush_para() in_code = True code_lang = line.strip()[3:].strip() code_buf = [] else: in_code = False code = "\n".join(code_buf) lang_attr = f' data-lang="{html.escape(code_lang)}"' if code_lang else "" out.append(f"
    {html.escape(code)}
    ") code_lang = "" code_buf = [] i += 1 continue if in_code: code_buf.append(line) i += 1 continue # hr if line.strip() == "---": flush_para() out.append("
    ") i += 1 continue # headings m = re.match(r"^(#{1,6})\s+(.*)$", line) if m: flush_para() level = len(m.group(1)) title = m.group(2).strip() out.append(f"{inline_format(html.escape(title))}") i += 1 continue # blockquote (single-line) if re.match(r"^\s*>\s?.*$", line): flush_para() q = re.sub(r"^\s*>\s?", "", line).strip() out.append(f"
    {inline_format(html.escape(q))}
    ") i += 1 continue # unordered list if re.match(r"^\s*-\s+", line): flush_para() items: list[str] = [] while i < len(lines) and re.match(r"^\s*-\s+", lines[i]): items.append(re.sub(r"^\s*-\s+", "", lines[i]).strip()) i += 1 flush_ul(items) continue # ordered list if re.match(r"^\s*\d+\.\s+", line): flush_para() items = [] while i < len(lines) and re.match(r"^\s*\d+\.\s+", lines[i]): items.append(re.sub(r"^\s*\d+\.\s+", "", lines[i]).strip()) i += 1 flush_ol(items) continue # blank line if line.strip() == "": flush_para() i += 1 continue # normal paragraph line para.append(line) i += 1 flush_para() body = "\n".join(out) return body def main() -> int: md_path = Path("docs/md_cursor/作业3_追踪Agent工具调用验收_cursor.md") md = md_path.read_text(encoding="utf-8") body_html = md_to_html(md) # 把 markdown 里的图片行改成可见图片(用简单替换即可) # md 里使用的是 ![...](绝对路径) 的写法,这里直接让它显示 body_html = body_html.replace( "

    ", "

    ", ) html_doc = f""" 作业3:在 Langfuse 中追踪 Agent 工具调用验收(HTML 渲染版) {body_html} """ out_path = Path("docs/html_cursor/作业3_追踪Agent工具调用验收_cursor.html") out_path.write_text(html_doc, encoding="utf-8") print("written:", out_path) return 0 if __name__ == "__main__": raise SystemExit(main())