/** * 用 Playwright 渲染 Mermaid .mmd 文件为高质量 PNG * 用法: node render_mermaid.js [width] */ const { chromium } = require('/Users/bing/node_modules/.pnpm/playwright@1.58.2/node_modules/playwright'); const fs = require('fs'); const path = require('path'); const mmdFile = process.argv[2]; const outFile = process.argv[3]; const width = parseInt(process.argv[4] || '2400', 10); if (!mmdFile || !outFile) { console.error('Usage: node render_mermaid.js [width]'); process.exit(1); } const mmdContent = fs.readFileSync(mmdFile, 'utf-8'); // 检测图表类型 const isMindmap = mmdContent.trim().startsWith('mindmap'); const isXYChart = mmdContent.includes('xychart-beta'); const html = `
${mmdContent}
`; (async () => { const browser = await chromium.launch(); const page = await browser.newPage({ viewport: { width: width, height: 1600 }, deviceScaleFactor: 2 }); await page.setContent(html, { waitUntil: 'networkidle' }); await page.waitForSelector('.mermaid svg', { timeout: 15000 }); await page.waitForTimeout(1000); const box = await page.locator('#diagram').boundingBox(); if (!box) { console.error('Failed to locate diagram'); await browser.close(); process.exit(1); } const padding = 40; await page.screenshot({ path: outFile, clip: { x: Math.max(0, box.x - padding), y: Math.max(0, box.y - padding), width: box.width + padding * 2, height: box.height + padding * 2 } }); console.log(`OK: ${outFile} (${Math.round(box.width)}x${Math.round(box.height)})`); await browser.close(); })();