UNPKG

penframe

Version:

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

341 lines (253 loc) 7.78 kB
# PenFrame [![npm version](https://badge.fury.io/js/penframe.svg)](https://badge.fury.io/js/penframe) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) A lightweight DSL-based wireframe and UI structure visualization tool. ✏️ Powered by PenFrame syntax. PenFrameは、シンプルなDSL(Domain Specific Language)を使ってワイヤーフレームやUI構造を記述し、SVG形式で可視化できるツールです。 ## Installation ### NPM Package ```bash npm install -g penframe ``` ### From Source ```bash git clone https://github.com/ai-program/penframe.git cd penframe npm install npm run build ``` ## Quick Start ### 1. Create a PenFrame file Create a file with `.pf` extension: ``` @app { width: 1200, height: 600, title: "My App" } @headline "Welcome" { level: 1, color: "#333" } @hr @p "Welcome to our app!" { align: "center" } @button "Get Started" { color: "#007bff", textColor: "#ffffff" } @tabs { items: ["Home", "Features", "Contact"], active: 0 } @badge "New" { color: "#e74c3c" } ``` ### 2. Generate SVG and PNG ```bash # Parse DSL to JSON AST penframe input.pf # Generate SVG penframe input.pf --svg output.svg # Generate PNG (using Puppeteer for high quality) penframe input.pf --png output.png # PNG with custom size and high DPI penframe input.pf --png output.png --width 1000 --scale 2 # PNG with custom background penframe input.pf --png output.png --background transparent # Convert AST JSON to PNG node src/ast2png.js examples/ast_sample.json output.png --width 800 --scale 3 ``` ## Supported Elements PenFrame supports the following UI elements: ### Basic Elements - `@headline "Text"` - Page headlines - `@p "Text"` - Text paragraphs - `@button "Text"` - Interactive buttons - `@hr` - Horizontal dividers ### Layout Elements - `@container {...}` - Container blocks - `@tabs { items: ["Tab1", "Tab2"] }` - Tab navigation - `@table [[...]]` - Data tables ### Form Elements - `@formcontrol "label" { control: "textbox" }` - Input fields - `@list { items: ["Item1", "Item2"] }` - Lists ### Media & Indicators - `@image { url: "path" }` - Images - `@badge "Text"` - Status badges ### Configuration Each element supports configuration options: ``` @button "Submit" { color: "#28a745", textColor: "#ffffff", width: 120, height: 40 } @tabs { items: ["Home", "Profile", "Settings"], active: 0, width: 300 } @badge "New" { color: "#dc3545", borderRadius: 8 } ``` ## Project Structure - `src/parser/grammar.pegjs` - PEG.js grammar definition - `dist/parser.js` - Built parser (generated) - `src/svg/astToSvg.js` - AST to SVG converter - `src/svg/astToPng.js` - AST to PNG converter (Puppeteer) - `src/cli.js` - Command line interface - `examples/` - Sample files and AST examples - `docs/` - Documentation ## Development ### Build Parser ```bash npm run build ``` ### Run Tests ```bash npm test ``` ### Parse DSL File ```bash npm start -- examples/sample.pf ``` ### Convert AST to SVG ```bash node src/svg/ast2svg.js examples/ast_sample.json output.svg ``` ### Convert AST to PNG ```bash node src/ast2png.js examples/ast_sample.json output.png --width 800 --scale 2 ``` ## API Usage ### Module Import (for VScode extensions, etc.) ```javascript // ES6 import (recommended for modern projects) import { penframeToSvg, penframeToPng, parse } from 'penframe'; // CommonJS require const { penframeToSvg, penframeToPng, parse } = require('penframe'); ``` ### Direct DSL to SVG/PNG Conversion ```javascript const { penframeToSvg, penframeToPng, penframeToPngFile } = require('penframe'); const fs = require('fs'); const dslCode = ` @headline "Hello World" { level: 1, color: "#333" } @button "Click Me" { color: "#007bff", textColor: "#ffffff" } @badge "New" { color: "#e74c3c" } `; // Convert to SVG const svg = penframeToSvg(dslCode); fs.writeFileSync('output.svg', svg); // Convert to PNG buffer (for in-memory use) const pngBuffer = await penframeToPng(dslCode, { width: 800, deviceScaleFactor: 2, background: 'white' }); // Convert to PNG file await penframeToPngFile(dslCode, 'output.png', { width: 800, height: 600, deviceScaleFactor: 2 }); ``` ### Lower-level API (AST-based) ```javascript const { parse, astToSvg, astToPngFile } = require('penframe'); const dslCode = fs.readFileSync('input.pf', 'utf8'); const ast = parse(dslCode); console.log(JSON.stringify(ast, null, 2)); const svg = astToSvg(ast); fs.writeFileSync('output.svg', svg); await astToPngFile(ast, 'output.png', { width: 800, height: 600, deviceScaleFactor: 2 }); ``` ## VSCode Extension Usage For VSCode extensions (like Mermaid preview), you can use PenFrame as follows: ```javascript // In your VSCode extension import { penframeToSvg } from 'penframe'; // Get PenFrame DSL from markdown code block const penframeDsl = ` @app { width: 800, height: 400, title: "My Wireframe" } @headline "Dashboard" { level: 1 } @tabs { items: ["Overview", "Analytics", "Settings"], active: 0 } @button "Save Changes" { color: "#28a745" } `; // Convert to SVG for preview const svgContent = penframeToSvg(penframeDsl); // Display in webview webviewPanel.webview.html = ` <!DOCTYPE html> <html> <body> ${svgContent} </body> </html> `; ``` ### Example Markdown Integration ````markdown ```penframe @app { width: 600, height: 300 } @headline "Login Form" { level: 2 } @formcontrol "Username" { control: "textbox" } @formcontrol "Password" { control: "textbox" } @button "Login" { color: "#007bff" } ``` ```` ## Browser Usage PenFrame can also be used directly in browsers via CDN or by downloading the minified file. ### CDN Usage ```html <!-- Include PenFrame from CDN --> <script src="https://unpkg.com/penframe@latest/dist/penframe.min.js"></script> <script> // Parse DSL const dslCode = ` @app { width: 600, height: 300, title: "My App" } @headline "Hello Browser!" { level: 1 } @button "Click Me" { color: "#007bff" } `; // Generate SVG const svg = PenFrame.penframeToSvg(dslCode); document.body.innerHTML = svg; // Generate PNG Data URL PenFrame.penframeToPngDataURL(dslCode, { width: 600, height: 400, scale: 2 }).then(dataURL => { const img = document.createElement('img'); img.src = dataURL; document.body.appendChild(img); }); </script> ``` ### Local File Usage 1. Download `penframe.min.js` from the releases 2. Include it in your HTML: ```html <script src="./penframe.min.js"></script> <script> // Use PenFrame global object const svg = PenFrame.penframeToSvg('@headline "Hello!" { level: 1 }'); </script> ``` ### Browser API The browser version provides: - `PenFrame.parse(dslCode)` - Parse DSL to AST - `PenFrame.penframeToSvg(dslCode)` - Convert DSL to SVG - `PenFrame.penframeToPngDataURL(dslCode, options)` - Convert to PNG Data URL - `PenFrame.penframeToPngBlob(dslCode, options)` - Convert to PNG Blob Note: Browser version uses Canvas API for PNG generation instead of Puppeteer. ### Live Demo Check out the live demo at `examples/browser-demo.html` after building: ```bash npm run build:browser # Open examples/browser-demo.html in your browser ``` ## Contributing 1. Fork the repository 2. Create your feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add some amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## Links - [GitHub Repository](https://github.com/ai-program/penframe) - [npm Package](https://www.npmjs.com/package/penframe) - [Issues](https://github.com/ai-program/penframe/issues)