UNPKG

penframe

Version:

A lightweight DSL-based wireframe and UI structure visualization tool.

99 lines (85 loc) 3.87 kB
#!/usr/bin/env node const fs = require('fs'); const path = require('path'); const parser = require('../dist/parser.js'); const astToSvg = require('./svg/astToSvg'); const { astToPngFile } = require('./svg/astToPng'); const main = async () => { const args = process.argv.slice(2); const filePath = args[0]; if (!filePath || args.includes('--help') || args.includes('-h')) { console.log('PenFrame - DSL-based wireframe visualization tool'); console.log(''); console.log('Usage: penframe <input.pf> [options]'); console.log(''); console.log('Options:'); console.log(' --svg <output.svg> Generate SVG file'); console.log(' --png <output.png> Generate PNG file (using Puppeteer)'); console.log(' --width <number> PNG viewport width'); console.log(' --height <number> PNG viewport height'); console.log(' --scale <number> PNG device scale factor (default: 2)'); console.log(' --background <color> PNG background (default: white)'); console.log(' --json Output JSON AST only (default)'); console.log(' --help, -h Show this help'); console.log(''); console.log('Examples:'); console.log(' penframe input.pf # Output JSON AST'); console.log(' penframe input.pf --svg output.svg # Generate SVG'); console.log(' penframe input.pf --png output.png # Generate PNG'); console.log(' penframe input.pf --png output.png --width 800 --height 600 --scale 3'); process.exit(args.includes('--help') || args.includes('-h') ? 0 : 1); } const absolutePath = path.resolve(filePath); if (!fs.existsSync(absolutePath)) { console.error(`Error: File not found at ${absolutePath}`); process.exit(1); } // Parse command line options const svgIndex = args.indexOf('--svg'); const pngIndex = args.indexOf('--png'); const widthIndex = args.indexOf('--width'); const heightIndex = args.indexOf('--height'); const scaleIndex = args.indexOf('--scale'); const backgroundIndex = args.indexOf('--background'); const svgOutput = svgIndex >= 0 ? args[svgIndex + 1] : null; const pngOutput = pngIndex >= 0 ? args[pngIndex + 1] : null; const pngOptions = {}; if (widthIndex >= 0) pngOptions.width = parseInt(args[widthIndex + 1]); if (heightIndex >= 0) pngOptions.height = parseInt(args[heightIndex + 1]); if (scaleIndex >= 0) pngOptions.deviceScaleFactor = parseFloat(args[scaleIndex + 1]); if (backgroundIndex >= 0) pngOptions.background = args[backgroundIndex + 1]; try { const content = fs.readFileSync(absolutePath, 'utf8'); const ast = parser.parse(content); // Generate outputs based on options if (svgOutput) { const svgContent = astToSvg(ast); fs.writeFileSync(svgOutput, svgContent); console.log(`✓ SVG saved to: ${svgOutput}`); } if (pngOutput) { console.log(`Converting to PNG using Puppeteer...`); await astToPngFile(ast, pngOutput, pngOptions); console.log(`✓ PNG saved to: ${pngOutput}`); const stats = fs.statSync(pngOutput); console.log(`File size: ${(stats.size / 1024).toFixed(1)} KB`); } // Default: output JSON AST if no other output specified if (!svgOutput && !pngOutput) { console.log(JSON.stringify(ast, null, 2)); } } catch (error) { if (error.name === 'SyntaxError') { console.error(`Syntax Error in ${absolutePath}:`); console.error(`Line ${error.location.start.line}, Column ${error.location.start.column}`); console.error(error.message); } else { console.error('An unexpected error occurred:', error.message); } process.exit(1); } }; main().catch(error => { console.error('Unexpected error:', error); process.exit(1); });