Update: 将子项目从 submodule 转为完整内容
- 移除 GovAI, nomifun-tauri, 算力盒子 的 submodule 引用 - 添加所有子项目的完整源代码 - 保留原始 .git 为 .git.bak 备份
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env npx tsx
|
||||
// @ts-nocheck
|
||||
/**
|
||||
* Mermaid diagram renderer using beautiful-mermaid
|
||||
* Usage:
|
||||
* npx tsx render.ts <mermaid-file> [--ascii] [--theme <theme>] [--output <file>]
|
||||
* echo "graph TD; A-->B" | npx tsx render.ts --stdin [--ascii]
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
// Auto-install beautiful-mermaid if not present
|
||||
async function ensureDependency(): Promise<void> {
|
||||
try {
|
||||
await import('beautiful-mermaid');
|
||||
} catch {
|
||||
console.error('Installing beautiful-mermaid...');
|
||||
execSync('npm install beautiful-mermaid', { stdio: 'inherit' });
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamic import for beautiful-mermaid (ESM module)
|
||||
async function loadMermaid() {
|
||||
await ensureDependency();
|
||||
const mod = await import('beautiful-mermaid');
|
||||
return mod;
|
||||
}
|
||||
|
||||
interface Options {
|
||||
input?: string;
|
||||
stdin: boolean;
|
||||
ascii: boolean;
|
||||
theme?: string;
|
||||
output?: string;
|
||||
}
|
||||
|
||||
function parseArgs(args: string[]): Options {
|
||||
const options: Options = { stdin: false, ascii: false };
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
if (arg === '--stdin') {
|
||||
options.stdin = true;
|
||||
} else if (arg === '--ascii') {
|
||||
options.ascii = true;
|
||||
} else if (arg === '--theme' && args[i + 1]) {
|
||||
options.theme = args[++i];
|
||||
} else if (arg === '--output' && args[i + 1]) {
|
||||
options.output = args[++i];
|
||||
} else if (!arg.startsWith('-')) {
|
||||
options.input = arg;
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
function readStdin(): Promise<string> {
|
||||
return new Promise((resolve) => {
|
||||
let data = '';
|
||||
process.stdin.setEncoding('utf8');
|
||||
process.stdin.on('readable', () => {
|
||||
let chunk;
|
||||
while ((chunk = process.stdin.read()) !== null) {
|
||||
data += chunk;
|
||||
}
|
||||
});
|
||||
process.stdin.on('end', () => resolve(data.trim()));
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.includes('--help') || args.includes('-h')) {
|
||||
console.log(`
|
||||
Mermaid Diagram Renderer (beautiful-mermaid)
|
||||
|
||||
Usage:
|
||||
npx tsx render.ts <file.mmd> [options]
|
||||
echo "graph TD; A-->B" | npx tsx render.ts --stdin [options]
|
||||
|
||||
Options:
|
||||
--ascii Output ASCII art instead of SVG
|
||||
--theme <name> Theme name (e.g., github-dark, dracula, nord)
|
||||
--output <file> Write to file instead of stdout
|
||||
--stdin Read mermaid code from stdin
|
||||
-h, --help Show this help
|
||||
|
||||
Supported diagram types:
|
||||
- Flowcharts (graph TD/LR/etc)
|
||||
- Sequence diagrams
|
||||
- State diagrams
|
||||
- Class diagrams
|
||||
- ER diagrams
|
||||
|
||||
Examples:
|
||||
npx tsx render.ts diagram.mmd --output diagram.svg
|
||||
npx tsx render.ts diagram.mmd --ascii
|
||||
echo "graph LR; A-->B-->C" | npx tsx render.ts --stdin --ascii
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const options = parseArgs(args);
|
||||
|
||||
// Get mermaid code
|
||||
let mermaidCode: string;
|
||||
if (options.stdin) {
|
||||
mermaidCode = await readStdin();
|
||||
} else if (options.input) {
|
||||
const filePath = resolve(options.input);
|
||||
if (!existsSync(filePath)) {
|
||||
console.error(`Error: File not found: ${filePath}`);
|
||||
process.exit(1);
|
||||
}
|
||||
mermaidCode = readFileSync(filePath, 'utf8');
|
||||
} else {
|
||||
console.error('Error: No input provided. Use --stdin or provide a file path.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!mermaidCode.trim()) {
|
||||
console.error('Error: Empty mermaid code');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
const mermaid = await loadMermaid();
|
||||
let result: string;
|
||||
|
||||
if (options.ascii) {
|
||||
// ASCII output
|
||||
result = mermaid.renderMermaidAscii(mermaidCode);
|
||||
} else {
|
||||
// SVG output - theme must be an object, not a string
|
||||
let themeColors = undefined;
|
||||
if (options.theme && mermaid.THEMES) {
|
||||
themeColors = mermaid.THEMES[options.theme];
|
||||
if (!themeColors) {
|
||||
console.error(
|
||||
`Warning: Unknown theme "${options.theme}". Available: ${Object.keys(mermaid.THEMES).join(', ')}`
|
||||
);
|
||||
}
|
||||
}
|
||||
result = await mermaid.renderMermaid(mermaidCode, themeColors);
|
||||
}
|
||||
|
||||
if (options.output) {
|
||||
writeFileSync(options.output, result);
|
||||
console.error(`Written to: ${options.output}`);
|
||||
} else {
|
||||
console.log(result);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error rendering diagram:', error instanceof Error ? error.message : error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user