文件预览

render_mermaid.py

查看 corporate-doc-builder 技能包中的文件内容。

文件内容

scripts/render_mermaid.py

#!/usr/bin/env python3
"""
render_mermaid.py — Extract and render Mermaid diagrams from Markdown.

Finds all ```mermaid fenced blocks in a Markdown file, writes each to
a .mmd file, and renders each to PNG via mmdc (Mermaid CLI).

Usage:
    python render_mermaid.py <markdown_file> <output_image_dir>

Requirements:
    - Node.js with npx available on PATH
    - puppeteer-config.json in the same directory as this script
      (enables --no-sandbox for Linux/container environments)

Output:
    diagram_1.png, diagram_2.png, ... in the output directory.
    This naming convention matches inject_docx.py's expectations.
"""
import os
import re
import subprocess
import sys


def extract_and_render(md_file, output_dir):
    """Extract all mermaid blocks from a Markdown file and render to PNG."""
    os.makedirs(output_dir, exist_ok=True)

    with open(md_file, "r", encoding="utf-8") as f:
        content = f.read()

    blocks = re.findall(r"```mermaid\n(.*?)```", content, re.DOTALL)
    print(f"Found {len(blocks)} mermaid blocks.")

    script_dir = os.path.dirname(os.path.abspath(__file__))
    puppeteer_cfg = os.path.join(script_dir, "puppeteer-config.json")
    puppeteer_args = ["-p", puppeteer_cfg] if os.path.exists(puppeteer_cfg) else []

    for i, block in enumerate(blocks, 1):
        mmd_path = os.path.join(output_dir, f"diagram_{i}.mmd")
        png_path = os.path.join(output_dir, f"diagram_{i}.png")

        with open(mmd_path, "w", encoding="utf-8") as f:
            f.write(block.strip())

        print(f"Rendering diagram {i}...")
        cmd = [
            "npx", "-y", "@mermaid-js/mermaid-cli",
            "-i", mmd_path,
            "-o", png_path,
            "-b", "white",
            "-s", "2",
        ] + puppeteer_args

        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            print(f"Successfully rendered {png_path}")
        else:
            print(f"ERROR rendering diagram {i}: {result.stderr}")


if __name__ == "__main__":
    if len(sys.argv) >= 3:
        md = sys.argv[1]
        out = sys.argv[2]
    else:
        print("Usage: python render_mermaid.py <markdown_file> <output_image_dir>")
        sys.exit(1)
    extract_and_render(md, out)