✨ initial commit
This commit is contained in:
173
examples/01-basic/main.go
Normal file
173
examples/01-basic/main.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/landaiqing/freezelib"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("🎯 Basic Usage Examples")
|
||||
fmt.Println("=======================")
|
||||
|
||||
// Create output directory
|
||||
os.MkdirAll("./output", 0755)
|
||||
|
||||
// Run basic examples
|
||||
simpleExample()
|
||||
helloWorldExample()
|
||||
quickStartExample()
|
||||
defaultConfigExample()
|
||||
|
||||
fmt.Println("\n✅ Basic examples completed!")
|
||||
fmt.Println("📁 Check the 'output' directory for generated files.")
|
||||
}
|
||||
|
||||
// Simple example - minimal code
|
||||
func simpleExample() {
|
||||
fmt.Println("\n📝 Simple Example")
|
||||
fmt.Println("------------------")
|
||||
|
||||
freeze := freezelib.New()
|
||||
|
||||
code := `fmt.Println("Hello, FreezeLib!")`
|
||||
|
||||
// Generate SVG
|
||||
svgData, err := freeze.GenerateFromCode(code, "go")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile("output/simple.svg", svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("✅ Generated: output/simple.svg")
|
||||
}
|
||||
|
||||
// Hello World example - classic first program
|
||||
func helloWorldExample() {
|
||||
fmt.Println("\n👋 Hello World Example")
|
||||
fmt.Println("-----------------------")
|
||||
|
||||
freeze := freezelib.New()
|
||||
|
||||
code := `package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("Hello, World!")
|
||||
fmt.Println("Welcome to FreezeLib!")
|
||||
|
||||
// This is a comment
|
||||
for i := 1; i <= 3; i++ {
|
||||
fmt.Printf("Count: %d\n", i)
|
||||
}
|
||||
}`
|
||||
|
||||
// Generate both SVG and PNG
|
||||
svgData, err := freeze.GenerateFromCode(code, "go")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error generating SVG: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
pngData, err := freeze.GeneratePNGFromCode(code, "go")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error generating PNG: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Save files
|
||||
os.WriteFile("output/hello_world.svg", svgData, 0644)
|
||||
os.WriteFile("output/hello_world.png", pngData, 0644)
|
||||
|
||||
fmt.Println("✅ Generated: output/hello_world.svg")
|
||||
fmt.Println("✅ Generated: output/hello_world.png")
|
||||
}
|
||||
|
||||
// Quick start example - using QuickFreeze API
|
||||
func quickStartExample() {
|
||||
fmt.Println("\n⚡ Quick Start Example")
|
||||
fmt.Println("----------------------")
|
||||
|
||||
qf := freezelib.NewQuickFreeze()
|
||||
|
||||
code := `function greet(name) {
|
||||
return "Hello, " + name + "!";
|
||||
}
|
||||
|
||||
const message = greet("FreezeLib");
|
||||
console.log(message);
|
||||
|
||||
// Arrow function example
|
||||
const multiply = (a, b) => a * b;
|
||||
console.log("5 * 3 =", multiply(5, 3));`
|
||||
|
||||
// Use QuickFreeze with basic styling
|
||||
svgData, err := qf.WithTheme("github").
|
||||
WithFont("JetBrains Mono", 14).
|
||||
WithLineNumbers().
|
||||
CodeToSVG(code)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile("output/quick_start.svg", svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("✅ Generated: output/quick_start.svg")
|
||||
}
|
||||
|
||||
// Default configuration example
|
||||
func defaultConfigExample() {
|
||||
fmt.Println("\n⚙️ Default Configuration Example")
|
||||
fmt.Println("---------------------------------")
|
||||
|
||||
// Show what default configuration looks like
|
||||
config := freezelib.DefaultConfig()
|
||||
freeze := freezelib.NewWithConfig(config)
|
||||
|
||||
code := `# Python Example
|
||||
def fibonacci(n):
|
||||
"""Calculate fibonacci number recursively."""
|
||||
if n <= 1:
|
||||
return n
|
||||
return fibonacci(n-1) + fibonacci(n-2)
|
||||
|
||||
# Generate first 10 fibonacci numbers
|
||||
print("Fibonacci sequence:")
|
||||
for i in range(10):
|
||||
print(f"F({i}) = {fibonacci(i)}")`
|
||||
|
||||
svgData, err := freeze.GenerateFromCode(code, "python")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile("output/default_config.svg", svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("✅ Generated: output/default_config.svg")
|
||||
|
||||
// Print configuration details
|
||||
fmt.Println("\n📋 Default Configuration:")
|
||||
fmt.Printf(" Theme: %s\n", config.Theme)
|
||||
fmt.Printf(" Font: %s, %dpt\n", config.Font.Family, config.Font.Size)
|
||||
fmt.Printf(" Background: %s\n", config.Background)
|
||||
fmt.Printf(" Window: %t\n", config.Window)
|
||||
fmt.Printf(" Line Numbers: %t\n", config.ShowLineNumbers)
|
||||
}
|
337
examples/02-formats/main.go
Normal file
337
examples/02-formats/main.go
Normal file
@@ -0,0 +1,337 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/landaiqing/freezelib"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("📊 Output Format Examples")
|
||||
fmt.Println("=========================")
|
||||
|
||||
// Create output directory
|
||||
os.MkdirAll("output", 0755)
|
||||
|
||||
// Run format examples
|
||||
svgVsPngExample()
|
||||
qualityComparisonExample()
|
||||
dimensionExamples()
|
||||
formatOptimizationExample()
|
||||
|
||||
fmt.Println("\n✅ Format examples completed!")
|
||||
fmt.Println("📁 Check the 'output' directory for generated files.")
|
||||
fmt.Println("📏 Compare file sizes and visual quality between formats.")
|
||||
}
|
||||
|
||||
// SVG vs PNG comparison
|
||||
func svgVsPngExample() {
|
||||
fmt.Println("\n🆚 SVG vs PNG Comparison")
|
||||
fmt.Println("-------------------------")
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme("github-dark").
|
||||
WithFont("JetBrains Mono", 14).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(15, 0, 8)
|
||||
|
||||
code := `package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"log"
|
||||
)
|
||||
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", handler)
|
||||
fmt.Println("Server starting on :8080")
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}`
|
||||
|
||||
// Generate SVG
|
||||
svgData, err := freeze.GenerateFromCode(code, "go")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error generating SVG: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Generate PNG
|
||||
pngData, err := freeze.GeneratePNGFromCode(code, "go")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error generating PNG: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Save files
|
||||
svgPath := "output/comparison.svg"
|
||||
pngPath := "output/comparison.png"
|
||||
|
||||
os.WriteFile(svgPath, svgData, 0644)
|
||||
os.WriteFile(pngPath, pngData, 0644)
|
||||
|
||||
// Show file size comparison
|
||||
svgInfo, _ := os.Stat(svgPath)
|
||||
pngInfo, _ := os.Stat(pngPath)
|
||||
|
||||
fmt.Printf("✅ Generated: %s (%d bytes)\n", svgPath, svgInfo.Size())
|
||||
fmt.Printf("✅ Generated: %s (%d bytes)\n", pngPath, pngInfo.Size())
|
||||
fmt.Printf("📊 Size ratio: PNG is %.1fx larger than SVG\n",
|
||||
float64(pngInfo.Size())/float64(svgInfo.Size()))
|
||||
}
|
||||
|
||||
// Quality comparison with different settings
|
||||
func qualityComparisonExample() {
|
||||
fmt.Println("\n🎨 Quality Comparison")
|
||||
fmt.Println("---------------------")
|
||||
|
||||
baseCode := `def quicksort(arr):
|
||||
if len(arr) <= 1:
|
||||
return arr
|
||||
|
||||
pivot = arr[len(arr) // 2]
|
||||
left = [x for x in arr if x < pivot]
|
||||
middle = [x for x in arr if x == pivot]
|
||||
right = [x for x in arr if x > pivot]
|
||||
|
||||
return quicksort(left) + middle + quicksort(right)
|
||||
|
||||
# Example usage
|
||||
numbers = [3, 6, 8, 10, 1, 2, 1]
|
||||
sorted_numbers = quicksort(numbers)
|
||||
print(f"Original: {numbers}")
|
||||
print(f"Sorted: {sorted_numbers}")`
|
||||
|
||||
// Different quality settings
|
||||
configs := []struct {
|
||||
name string
|
||||
width float64
|
||||
height float64
|
||||
fontSize float64
|
||||
theme string
|
||||
}{
|
||||
{"low_quality", 400, 300, 10, "github"},
|
||||
{"medium_quality", 800, 600, 14, "github-dark"},
|
||||
{"high_quality", 1200, 900, 16, "dracula"},
|
||||
{"ultra_quality", 1600, 1200, 18, "monokai"},
|
||||
}
|
||||
|
||||
for _, config := range configs {
|
||||
fmt.Printf("🔧 Generating %s...\n", config.name)
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme(config.theme).
|
||||
WithFont("JetBrains Mono", config.fontSize).
|
||||
WithDimensions(config.width, config.height).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(10, 0, 5)
|
||||
|
||||
// Generate PNG for quality comparison
|
||||
pngData, err := freeze.GeneratePNGFromCode(baseCode, "python")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/quality_%s.png", config.name)
|
||||
err = os.WriteFile(filename, pngData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Show file info
|
||||
info, _ := os.Stat(filename)
|
||||
fmt.Printf("✅ Generated: %s (%dx%d, %d bytes)\n",
|
||||
filename, config.width, config.height, info.Size())
|
||||
}
|
||||
}
|
||||
|
||||
// Different dimension examples
|
||||
func dimensionExamples() {
|
||||
fmt.Println("\n📏 Dimension Examples")
|
||||
fmt.Println("---------------------")
|
||||
|
||||
code := `SELECT u.name, u.email, COUNT(o.id) as order_count
|
||||
FROM users u
|
||||
LEFT JOIN orders o ON u.id = o.user_id
|
||||
WHERE u.created_at >= '2024-01-01'
|
||||
GROUP BY u.id, u.name, u.email
|
||||
HAVING COUNT(o.id) > 0
|
||||
ORDER BY order_count DESC
|
||||
LIMIT 10;`
|
||||
|
||||
dimensions := []struct {
|
||||
name string
|
||||
width float64
|
||||
height float64
|
||||
desc string
|
||||
}{
|
||||
{"square", 600, 600, "Square format"},
|
||||
{"wide", 1000, 400, "Wide format (presentations)"},
|
||||
{"tall", 400, 800, "Tall format (mobile)"},
|
||||
{"standard", 800, 600, "Standard 4:3 ratio"},
|
||||
{"widescreen", 1200, 675, "Widescreen 16:9 ratio"},
|
||||
}
|
||||
|
||||
for _, dim := range dimensions {
|
||||
fmt.Printf("📐 Creating %s format (%fx%f)...\n", dim.name, dim.width, dim.height)
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme("nord").
|
||||
WithFont("Cascadia Code", 13).
|
||||
WithDimensions(dim.width, dim.height).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithPadding(20)
|
||||
|
||||
svgData, err := freeze.GenerateFromCode(code, "sql")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/dimension_%s.svg", dim.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s - %s\n", filename, dim.desc)
|
||||
}
|
||||
}
|
||||
|
||||
// Format optimization examples
|
||||
func formatOptimizationExample() {
|
||||
fmt.Println("\n⚡ Format Optimization")
|
||||
fmt.Println("----------------------")
|
||||
|
||||
code := `import React, { useState, useEffect } from 'react';
|
||||
|
||||
const TodoApp = () => {
|
||||
const [todos, setTodos] = useState([]);
|
||||
const [input, setInput] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
// Load todos from localStorage
|
||||
const saved = localStorage.getItem('todos');
|
||||
if (saved) {
|
||||
setTodos(JSON.parse(saved));
|
||||
}
|
||||
}, []);
|
||||
|
||||
const addTodo = () => {
|
||||
if (input.trim()) {
|
||||
const newTodo = {
|
||||
id: Date.now(),
|
||||
text: input,
|
||||
completed: false
|
||||
};
|
||||
setTodos([...todos, newTodo]);
|
||||
setInput('');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="todo-app">
|
||||
<h1>Todo List</h1>
|
||||
<input
|
||||
value={input}
|
||||
onChange={(e) => setInput(e.target.value)}
|
||||
placeholder="Add a todo..."
|
||||
/>
|
||||
<button onClick={addTodo}>Add</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TodoApp;`
|
||||
|
||||
// Optimized for different use cases
|
||||
optimizations := []struct {
|
||||
name string
|
||||
format string
|
||||
description string
|
||||
config func() *freezelib.Freeze
|
||||
}{
|
||||
{
|
||||
"web_optimized",
|
||||
"svg",
|
||||
"Optimized for web (small, scalable)",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("system-ui", 12).
|
||||
WithPadding(15).
|
||||
WithWindow(false) // No window for smaller size
|
||||
},
|
||||
},
|
||||
{
|
||||
"print_optimized",
|
||||
"png",
|
||||
"Optimized for print (high DPI)",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("Times New Roman", 14).
|
||||
WithDimensions(1200, 900).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(0, 0, 0) // No shadow for print
|
||||
},
|
||||
},
|
||||
{
|
||||
"social_optimized",
|
||||
"png",
|
||||
"Optimized for social media",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("dracula").
|
||||
WithFont("Fira Code", 16).
|
||||
WithDimensions(1080, 1080). // Square for Instagram
|
||||
WithWindow(true).
|
||||
WithShadow(20, 0, 15).
|
||||
WithPadding(30)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, opt := range optimizations {
|
||||
fmt.Printf("🎯 Creating %s (%s)...\n", opt.name, opt.description)
|
||||
|
||||
freeze := opt.config()
|
||||
|
||||
var data []byte
|
||||
var err error
|
||||
var filename string
|
||||
|
||||
if opt.format == "svg" {
|
||||
data, err = freeze.GenerateFromCode(code, "javascript")
|
||||
filename = fmt.Sprintf("output/optimized_%s.svg", opt.name)
|
||||
} else {
|
||||
data, err = freeze.GeneratePNGFromCode(code, "javascript")
|
||||
filename = fmt.Sprintf("output/optimized_%s.png", opt.name)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
err = os.WriteFile(filename, data, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
info, _ := os.Stat(filename)
|
||||
fmt.Printf("✅ Generated: %s (%d bytes)\n", filename, info.Size())
|
||||
}
|
||||
}
|
395
examples/03-themes/main.go
Normal file
395
examples/03-themes/main.go
Normal file
@@ -0,0 +1,395 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/landaiqing/freezelib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("🎨 Theme Showcase Examples")
|
||||
fmt.Println("===========================")
|
||||
|
||||
// Create output directory
|
||||
os.MkdirAll("output", 0755)
|
||||
|
||||
// Run theme examples
|
||||
popularThemesExample()
|
||||
lightVsDarkExample()
|
||||
themeComparisonExample()
|
||||
customThemeExample()
|
||||
|
||||
fmt.Println("\n✅ Theme examples completed!")
|
||||
fmt.Println("📁 Check the 'output' directory for generated files.")
|
||||
fmt.Println("🎨 Compare different themes and their visual styles.")
|
||||
}
|
||||
|
||||
// Popular themes showcase
|
||||
func popularThemesExample() {
|
||||
fmt.Println("\n🌟 Popular Themes Showcase")
|
||||
fmt.Println("--------------------------")
|
||||
|
||||
code := `class DataProcessor:
|
||||
def __init__(self, data_source):
|
||||
self.data_source = data_source
|
||||
self.processed_data = []
|
||||
|
||||
def process(self):
|
||||
"""Process the data with validation and transformation."""
|
||||
try:
|
||||
raw_data = self.load_data()
|
||||
validated_data = self.validate(raw_data)
|
||||
self.processed_data = self.transform(validated_data)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Processing failed: {e}")
|
||||
return False
|
||||
|
||||
def validate(self, data):
|
||||
# Remove null values and duplicates
|
||||
clean_data = [item for item in data if item is not None]
|
||||
return list(set(clean_data))
|
||||
|
||||
def transform(self, data):
|
||||
# Apply business logic transformations
|
||||
return [item.upper() if isinstance(item, str) else item
|
||||
for item in data]`
|
||||
|
||||
// Popular themes to showcase
|
||||
themes := []struct {
|
||||
name string
|
||||
description string
|
||||
}{
|
||||
{"github", "GitHub light theme - clean and professional"},
|
||||
{"github-dark", "GitHub dark theme - modern and sleek"},
|
||||
{"dracula", "Dracula theme - purple and pink accents"},
|
||||
{"monokai", "Monokai theme - classic dark with vibrant colors"},
|
||||
{"solarized-dark", "Solarized dark - easy on the eyes"},
|
||||
{"solarized-light", "Solarized light - warm and readable"},
|
||||
{"nord", "Nord theme - arctic, north-bluish color palette"},
|
||||
{"one-dark", "One Dark theme - Atom's signature theme"},
|
||||
{"material", "Material theme - Google's material design"},
|
||||
{"vim", "Vim theme - classic terminal colors"},
|
||||
}
|
||||
|
||||
for _, theme := range themes {
|
||||
fmt.Printf("🎨 Generating %s theme...\n", theme.name)
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme(theme.name).
|
||||
WithFont("JetBrains Mono", 14).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(15, 0, 8).
|
||||
WithPadding(20)
|
||||
|
||||
svgData, err := freeze.GenerateFromCode(code, "python")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error with theme %s: %v\n", theme.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/theme_%s.svg", theme.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving %s: %v\n", filename, err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s - %s\n", filename, theme.description)
|
||||
}
|
||||
}
|
||||
|
||||
// Light vs Dark theme comparison
|
||||
func lightVsDarkExample() {
|
||||
fmt.Println("\n☀️🌙 Light vs Dark Comparison")
|
||||
fmt.Println("------------------------------")
|
||||
|
||||
code := `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Modern Web App</title>
|
||||
<style>
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Welcome to Our App</h1>
|
||||
<div class="card">
|
||||
<h2>Features</h2>
|
||||
<p>This is a modern web application with responsive design.</p>
|
||||
<button class="btn-primary">Get Started</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>`
|
||||
|
||||
// Light and dark theme pairs
|
||||
themePairs := []struct {
|
||||
light string
|
||||
dark string
|
||||
name string
|
||||
}{
|
||||
{"github", "github-dark", "GitHub"},
|
||||
{"solarized-light", "solarized-dark", "Solarized"},
|
||||
{"material", "one-dark", "Material vs One Dark"},
|
||||
}
|
||||
|
||||
for _, pair := range themePairs {
|
||||
fmt.Printf("🔄 Comparing %s themes...\n", pair.name)
|
||||
|
||||
// Light theme
|
||||
lightFreeze := freezelib.New().
|
||||
WithTheme(pair.light).
|
||||
WithFont("SF Mono", 13).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(10, 0, 5).
|
||||
WithPadding(25)
|
||||
|
||||
lightData, err := lightFreeze.GenerateFromCode(code, "html")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error with light theme: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Dark theme
|
||||
darkFreeze := freezelib.New().
|
||||
WithTheme(pair.dark).
|
||||
WithFont("SF Mono", 13).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(15, 0, 10).
|
||||
WithPadding(25)
|
||||
|
||||
darkData, err := darkFreeze.GenerateFromCode(code, "html")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error with dark theme: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Save files
|
||||
lightFile := fmt.Sprintf("output/comparison_%s_light.svg",
|
||||
sanitizeFilename(pair.name))
|
||||
darkFile := fmt.Sprintf("output/comparison_%s_dark.svg",
|
||||
sanitizeFilename(pair.name))
|
||||
|
||||
os.WriteFile(lightFile, lightData, 0644)
|
||||
os.WriteFile(darkFile, darkData, 0644)
|
||||
|
||||
fmt.Printf("✅ Generated: %s (light)\n", lightFile)
|
||||
fmt.Printf("✅ Generated: %s (dark)\n", darkFile)
|
||||
}
|
||||
}
|
||||
|
||||
// Theme comparison grid
|
||||
func themeComparisonExample() {
|
||||
fmt.Println("\n📊 Theme Comparison Grid")
|
||||
fmt.Println("------------------------")
|
||||
|
||||
// Short code snippet for comparison
|
||||
code := `fn main() {
|
||||
let numbers = vec![1, 2, 3, 4, 5];
|
||||
|
||||
let doubled: Vec<i32> = numbers
|
||||
.iter()
|
||||
.map(|x| x * 2)
|
||||
.collect();
|
||||
|
||||
println!("Original: {:?}", numbers);
|
||||
println!("Doubled: {:?}", doubled);
|
||||
|
||||
// Pattern matching
|
||||
match doubled.len() {
|
||||
0 => println!("Empty vector"),
|
||||
1..=5 => println!("Small vector"),
|
||||
_ => println!("Large vector"),
|
||||
}
|
||||
}`
|
||||
|
||||
// Themes for comparison
|
||||
comparisonThemes := []string{
|
||||
"github", "github-dark", "dracula", "monokai",
|
||||
"nord", "one-dark", "material", "vim",
|
||||
}
|
||||
|
||||
for i, theme := range comparisonThemes {
|
||||
fmt.Printf("🎯 Creating comparison sample %d: %s\n", i+1, theme)
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme(theme).
|
||||
WithFont("Fira Code", 12).
|
||||
WithWindow(false). // No window for cleaner comparison
|
||||
WithLineNumbers(false).
|
||||
WithPadding(15).
|
||||
WithDimensions(600, 400) // Consistent size
|
||||
|
||||
svgData, err := freeze.GenerateFromCode(code, "rust")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/comparison_grid_%02d_%s.svg", i+1, theme)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s\n", filename)
|
||||
}
|
||||
}
|
||||
|
||||
// Custom theme example
|
||||
func customThemeExample() {
|
||||
fmt.Println("\n🎨 Custom Theme Example")
|
||||
fmt.Println("------------------------")
|
||||
|
||||
code := `package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Message string 'json:"message"'
|
||||
Data map[string]interface{} 'json:"data"'
|
||||
Status int 'json:"status"'
|
||||
}
|
||||
|
||||
func apiHandler(w http.ResponseWriter, r *http.Request) {
|
||||
response := Response{
|
||||
Message: "API is working!",
|
||||
Data: map[string]interface{}{
|
||||
"timestamp": "2024-01-15T10:30:00Z",
|
||||
"version": "1.0.0",
|
||||
"healthy": true,
|
||||
},
|
||||
Status: 200,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/api/status", apiHandler)
|
||||
fmt.Println("API server starting on :8080")
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}`
|
||||
|
||||
// Create custom-styled versions
|
||||
customStyles := []struct {
|
||||
name string
|
||||
config func() *freezelib.Freeze
|
||||
desc string
|
||||
}{
|
||||
{
|
||||
"corporate",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("Arial", 14).
|
||||
WithBackground("#f8f9fa").
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(5, 2, 3).
|
||||
WithBorder(1, 4, "#dee2e6").
|
||||
WithPadding(30)
|
||||
},
|
||||
"Corporate style - clean and professional",
|
||||
},
|
||||
{
|
||||
"cyberpunk",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("dracula").
|
||||
WithFont("Courier New", 13).
|
||||
WithBackground("#0d1117").
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(20, 0, 15).
|
||||
WithBorder(2, 0, "#ff79c6").
|
||||
WithPadding(25)
|
||||
},
|
||||
"Cyberpunk style - neon and futuristic",
|
||||
},
|
||||
{
|
||||
"minimal",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("system-ui", 13).
|
||||
WithBackground("#ffffff").
|
||||
WithWindow(false).
|
||||
WithLineNumbers(false).
|
||||
WithShadow(0, 0, 0).
|
||||
WithPadding(20)
|
||||
},
|
||||
"Minimal style - clean and distraction-free",
|
||||
},
|
||||
}
|
||||
|
||||
for _, style := range customStyles {
|
||||
fmt.Printf("✨ Creating %s style...\n", style.name)
|
||||
|
||||
freeze := style.config()
|
||||
svgData, err := freeze.GenerateFromCode(code, "go")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/custom_%s.svg", style.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s - %s\n", filename, style.desc)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to sanitize filenames
|
||||
func sanitizeFilename(name string) string {
|
||||
// Replace spaces and special characters with underscores
|
||||
result := ""
|
||||
for _, char := range name {
|
||||
if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') ||
|
||||
(char >= '0' && char <= '9') {
|
||||
result += string(char)
|
||||
} else {
|
||||
result += "_"
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
896
examples/04-languages/main.go
Normal file
896
examples/04-languages/main.go
Normal file
@@ -0,0 +1,896 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/landaiqing/freezelib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("💻 Programming Languages Examples")
|
||||
fmt.Println("=================================")
|
||||
|
||||
// Create output directory
|
||||
os.MkdirAll("output", 0755)
|
||||
|
||||
// Run language examples
|
||||
popularLanguagesExample()
|
||||
languageComparisonExample()
|
||||
multiLanguageProjectExample()
|
||||
languageSpecificFeaturesExample()
|
||||
|
||||
fmt.Println("\n✅ Language examples completed!")
|
||||
fmt.Println("📁 Check the 'output' directory for generated files.")
|
||||
}
|
||||
|
||||
// Popular programming languages showcase
|
||||
func popularLanguagesExample() {
|
||||
fmt.Println("\n🌟 Popular Languages Showcase")
|
||||
fmt.Println("-----------------------------")
|
||||
|
||||
// Language examples with sample code
|
||||
languages := []struct {
|
||||
name string
|
||||
code string
|
||||
lang string
|
||||
}{
|
||||
{
|
||||
"go",
|
||||
`package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("Hello from Go!")
|
||||
|
||||
// Goroutine example
|
||||
go func() {
|
||||
fmt.Println("This runs concurrently")
|
||||
}()
|
||||
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}`,
|
||||
"go",
|
||||
},
|
||||
{
|
||||
"python",
|
||||
`import asyncio
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class User:
|
||||
name: str
|
||||
age: int
|
||||
email: str
|
||||
|
||||
async def fetch_user(user_id: int) -> User:
|
||||
# Simulate API call
|
||||
await asyncio.sleep(1)
|
||||
return User(name="John Doe", age=30, email="john@example.com")
|
||||
|
||||
async def main():
|
||||
user = await fetch_user(123)
|
||||
print(f"User: {user.name}, {user.age}, {user.email}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())`,
|
||||
"python",
|
||||
},
|
||||
{
|
||||
"javascript",
|
||||
`// Modern JavaScript example
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const response = await fetch('https://api.example.com/data');
|
||||
const data = await response.json();
|
||||
|
||||
// Destructuring and spread operator
|
||||
const { items, meta } = data;
|
||||
const allItems = [...items, { id: 'new', value: 42 }];
|
||||
|
||||
// Array methods
|
||||
const filtered = allItems.filter(item => item.value > 10);
|
||||
|
||||
return filtered;
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
// Call the function
|
||||
fetchData().then(result => console.log(result));`,
|
||||
"javascript",
|
||||
},
|
||||
{
|
||||
"rust",
|
||||
`use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct User {
|
||||
name: String,
|
||||
age: u32,
|
||||
active: bool,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Create a new User
|
||||
let user = User {
|
||||
name: String::from("Alice"),
|
||||
age: 28,
|
||||
active: true,
|
||||
};
|
||||
|
||||
// Using a HashMap
|
||||
let mut scores = HashMap::new();
|
||||
scores.insert(String::from("Blue"), 10);
|
||||
scores.insert(String::from("Yellow"), 50);
|
||||
|
||||
// Pattern matching
|
||||
match user.age {
|
||||
0..=17 => println!("{} is underage", user.name),
|
||||
18..=64 => println!("{} is an adult", user.name),
|
||||
_ => println!("{} is a senior", user.name),
|
||||
}
|
||||
}`,
|
||||
"rust",
|
||||
},
|
||||
{
|
||||
"java",
|
||||
`import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class StreamExample {
|
||||
public static void main(String[] args) {
|
||||
// Create a list of names
|
||||
List<String> names = List.of("Alice", "Bob", "Charlie", "David");
|
||||
|
||||
// Use streams to filter and transform
|
||||
List<String> filteredNames = names.stream()
|
||||
.filter(name -> name.length() > 4)
|
||||
.map(String::toUpperCase)
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Print the results
|
||||
System.out.println("Original names: " + names);
|
||||
System.out.println("Filtered names: " + filteredNames);
|
||||
}
|
||||
}`,
|
||||
"java",
|
||||
},
|
||||
{
|
||||
"csharp",
|
||||
`using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace LinqExample
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// Create a list of products
|
||||
var products = new List<Product>
|
||||
{
|
||||
new Product { Id = 1, Name = "Laptop", Price = 1200.00m, Category = "Electronics" },
|
||||
new Product { Id = 2, Name = "Desk Chair", Price = 250.50m, Category = "Furniture" },
|
||||
new Product { Id = 3, Name = "Coffee Maker", Price = 89.99m, Category = "Kitchen" },
|
||||
new Product { Id = 4, Name = "Tablet", Price = 400.00m, Category = "Electronics" }
|
||||
};
|
||||
|
||||
// Use LINQ to query products
|
||||
var expensiveElectronics = products
|
||||
.Where(p => p.Category == "Electronics" && p.Price > 500)
|
||||
.OrderBy(p => p.Price)
|
||||
.Select(p => new { p.Name, p.Price });
|
||||
|
||||
Console.WriteLine("Expensive Electronics:");
|
||||
foreach (var item in expensiveElectronics)
|
||||
{
|
||||
Console.WriteLine($"{item.Name}: ${item.Price}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Product
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public string Category { get; set; }
|
||||
}
|
||||
}`,
|
||||
"csharp",
|
||||
},
|
||||
}
|
||||
|
||||
// Create a consistent style for all languages
|
||||
freeze := freezelib.New().
|
||||
WithTheme("github-dark").
|
||||
WithFont("JetBrains Mono", 14).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(15, 0, 8).
|
||||
WithPadding(20)
|
||||
|
||||
for _, lang := range languages {
|
||||
fmt.Printf("📝 Generating %s example...\n", lang.name)
|
||||
|
||||
svgData, err := freeze.GenerateFromCode(lang.code, lang.lang)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error with %s: %v\n", lang.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/language_%s.svg", lang.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving %s: %v\n", filename, err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s\n", filename)
|
||||
}
|
||||
}
|
||||
|
||||
// Language comparison with the same algorithm
|
||||
func languageComparisonExample() {
|
||||
fmt.Println("\n🔄 Same Algorithm in Different Languages")
|
||||
fmt.Println("---------------------------------------")
|
||||
|
||||
// Fibonacci implementation in different languages
|
||||
fibImplementations := []struct {
|
||||
name string
|
||||
code string
|
||||
lang string
|
||||
}{
|
||||
{
|
||||
"go",
|
||||
`package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Recursive Fibonacci implementation
|
||||
func fibonacci(n int) int {
|
||||
if n <= 1 {
|
||||
return n
|
||||
}
|
||||
return fibonacci(n-1) + fibonacci(n-2)
|
||||
}
|
||||
|
||||
// Iterative Fibonacci implementation
|
||||
func fibonacciIterative(n int) int {
|
||||
if n <= 1 {
|
||||
return n
|
||||
}
|
||||
|
||||
a, b := 0, 1
|
||||
for i := 2; i <= n; i++ {
|
||||
a, b = b, a+b
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func main() {
|
||||
n := 10
|
||||
fmt.Printf("Fibonacci(%d) = %d (recursive)\n", n, fibonacci(n))
|
||||
fmt.Printf("Fibonacci(%d) = %d (iterative)\n", n, fibonacciIterative(n))
|
||||
}`,
|
||||
"go",
|
||||
},
|
||||
{
|
||||
"python",
|
||||
`def fibonacci_recursive(n):
|
||||
"""Calculate Fibonacci number recursively."""
|
||||
if n <= 1:
|
||||
return n
|
||||
return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)
|
||||
|
||||
def fibonacci_iterative(n):
|
||||
"""Calculate Fibonacci number iteratively."""
|
||||
if n <= 1:
|
||||
return n
|
||||
|
||||
a, b = 0, 1
|
||||
for i in range(2, n+1):
|
||||
a, b = b, a + b
|
||||
return b
|
||||
|
||||
def fibonacci_dynamic(n):
|
||||
"""Calculate Fibonacci number using dynamic programming."""
|
||||
memo = {0: 0, 1: 1}
|
||||
|
||||
def fib(n):
|
||||
if n not in memo:
|
||||
memo[n] = fib(n-1) + fib(n-2)
|
||||
return memo[n]
|
||||
|
||||
return fib(n)
|
||||
|
||||
# Test the functions
|
||||
n = 10
|
||||
print(f"Fibonacci({n}) = {fibonacci_recursive(n)} (recursive)")
|
||||
print(f"Fibonacci({n}) = {fibonacci_iterative(n)} (iterative)")
|
||||
print(f"Fibonacci({n}) = {fibonacci_dynamic(n)} (dynamic)")`,
|
||||
"python",
|
||||
},
|
||||
{
|
||||
"javascript",
|
||||
`// Recursive Fibonacci implementation
|
||||
function fibonacciRecursive(n) {
|
||||
if (n <= 1) return n;
|
||||
return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2);
|
||||
}
|
||||
|
||||
// Iterative Fibonacci implementation
|
||||
function fibonacciIterative(n) {
|
||||
if (n <= 1) return n;
|
||||
|
||||
let a = 0, b = 1;
|
||||
for (let i = 2; i <= n; i++) {
|
||||
const temp = a + b;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
// Fibonacci with memoization
|
||||
function fibonacciMemoized(n, memo = {}) {
|
||||
if (n in memo) return memo[n];
|
||||
if (n <= 1) return n;
|
||||
|
||||
memo[n] = fibonacciMemoized(n - 1, memo) + fibonacciMemoized(n - 2, memo);
|
||||
return memo[n];
|
||||
}
|
||||
|
||||
// Test the functions
|
||||
const n = 10;
|
||||
console.log(Fibonacci(${n}) = ${fibonacciRecursive(n)} (recursive));
|
||||
console.log(Fibonacci(${n}) = ${fibonacciIterative(n)} (iterative));
|
||||
console.log(Fibonacci(${n}) = ${fibonacciMemoized(n)} (memoized));`,
|
||||
"javascript",
|
||||
},
|
||||
{
|
||||
"rust",
|
||||
`fn fibonacci_recursive(n: u32) -> u32 {
|
||||
match n {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
_ => fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2),
|
||||
}
|
||||
}
|
||||
|
||||
fn fibonacci_iterative(n: u32) -> u32 {
|
||||
match n {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
_ => {
|
||||
let mut a = 0;
|
||||
let mut b = 1;
|
||||
|
||||
for _ in 2..=n {
|
||||
let temp = a + b;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
b
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let n = 10;
|
||||
println!("Fibonacci({}) = {} (recursive)", n, fibonacci_recursive(n));
|
||||
println!("Fibonacci({}) = {} (iterative)", n, fibonacci_iterative(n));
|
||||
}`,
|
||||
"rust",
|
||||
},
|
||||
}
|
||||
|
||||
// Create a consistent style for comparison
|
||||
freeze := freezelib.New().
|
||||
WithTheme("dracula").
|
||||
WithFont("Fira Code", 14).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithPadding(20)
|
||||
|
||||
for _, impl := range fibImplementations {
|
||||
fmt.Printf("🧮 Generating Fibonacci in %s...\n", impl.name)
|
||||
|
||||
svgData, err := freeze.GenerateFromCode(impl.code, impl.lang)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error with %s: %v\n", impl.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/fibonacci_%s.svg", impl.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving %s: %v\n", filename, err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s\n", filename)
|
||||
}
|
||||
}
|
||||
|
||||
// Multi-language project example
|
||||
func multiLanguageProjectExample() {
|
||||
fmt.Println("\n🌐 Multi-language Project")
|
||||
fmt.Println("-------------------------")
|
||||
|
||||
// Different files in a web project
|
||||
projectFiles := []struct {
|
||||
name string
|
||||
code string
|
||||
lang string
|
||||
filename string
|
||||
}{
|
||||
{
|
||||
"HTML",
|
||||
`<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Task Manager</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Task Manager</h1>
|
||||
|
||||
<div class="task-form">
|
||||
<input type="text" id="taskInput" placeholder="Add a new task...">
|
||||
<button id="addTask">Add</button>
|
||||
</div>
|
||||
|
||||
<ul id="taskList" class="task-list"></ul>
|
||||
|
||||
<div class="stats">
|
||||
<p>Total tasks: <span id="totalTasks">0</span></p>
|
||||
<p>Completed: <span id="completedTasks">0</span></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>`,
|
||||
"html",
|
||||
"index.html",
|
||||
},
|
||||
{
|
||||
"CSS",
|
||||
`/* Task Manager Styles */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
line-height: 1.6;
|
||||
background-color: #f5f5f5;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 2rem auto;
|
||||
padding: 2rem;
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.task-form {
|
||||
display: flex;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
#taskInput {
|
||||
flex: 1;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px 0 0 4px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
#addTask {
|
||||
padding: 0.75rem 1.5rem;
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 0 4px 4px 0;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.task-list {
|
||||
list-style: none;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.task-list li {
|
||||
padding: 1rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.task-list li.completed {
|
||||
text-decoration: line-through;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
.stats {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #7f8c8d;
|
||||
font-size: 0.9rem;
|
||||
}`,
|
||||
"css",
|
||||
"styles.css",
|
||||
},
|
||||
{
|
||||
"JavaScript",
|
||||
`// Task Manager App
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// DOM Elements
|
||||
const taskInput = document.getElementById('taskInput');
|
||||
const addTaskBtn = document.getElementById('addTask');
|
||||
const taskList = document.getElementById('taskList');
|
||||
const totalTasksEl = document.getElementById('totalTasks');
|
||||
const completedTasksEl = document.getElementById('completedTasks');
|
||||
|
||||
// Task array
|
||||
let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
|
||||
|
||||
// Initial render
|
||||
renderTasks();
|
||||
updateStats();
|
||||
|
||||
// Event Listeners
|
||||
addTaskBtn.addEventListener('click', addTask);
|
||||
taskInput.addEventListener('keypress', e => {
|
||||
if (e.key === 'Enter') addTask();
|
||||
});
|
||||
|
||||
// Add a new task
|
||||
function addTask() {
|
||||
const taskText = taskInput.value.trim();
|
||||
if (taskText === '') return;
|
||||
|
||||
tasks.push({
|
||||
id: Date.now(),
|
||||
text: taskText,
|
||||
completed: false
|
||||
});
|
||||
|
||||
saveToLocalStorage();
|
||||
renderTasks();
|
||||
updateStats();
|
||||
|
||||
taskInput.value = '';
|
||||
taskInput.focus();
|
||||
}
|
||||
|
||||
// Toggle task completion
|
||||
function toggleTask(id) {
|
||||
tasks = tasks.map(task =>
|
||||
task.id === id ? { ...task, completed: !task.completed } : task
|
||||
);
|
||||
|
||||
saveToLocalStorage();
|
||||
renderTasks();
|
||||
updateStats();
|
||||
}
|
||||
|
||||
// Delete a task
|
||||
function deleteTask(id) {
|
||||
tasks = tasks.filter(task => task.id !== id);
|
||||
|
||||
saveToLocalStorage();
|
||||
renderTasks();
|
||||
updateStats();
|
||||
}
|
||||
|
||||
// Render tasks to DOM
|
||||
function renderTasks() {
|
||||
taskList.innerHTML = '';
|
||||
|
||||
tasks.forEach(task => {
|
||||
const li = document.createElement('li');
|
||||
li.className = task.completed ? 'completed' : '';
|
||||
|
||||
li.innerHTML =
|
||||
<span onclick="toggleTask(${task.id})">${task.text}</span>
|
||||
<button onclick="deleteTask(${task.id})">Delete</button>
|
||||
;
|
||||
|
||||
taskList.appendChild(li);
|
||||
});
|
||||
}
|
||||
|
||||
// Update statistics
|
||||
function updateStats() {
|
||||
totalTasksEl.textContent = tasks.length;
|
||||
completedTasksEl.textContent = tasks.filter(task => task.completed).length;
|
||||
}
|
||||
|
||||
// Save to localStorage
|
||||
function saveToLocalStorage() {
|
||||
localStorage.setItem('tasks', JSON.stringify(tasks));
|
||||
}
|
||||
|
||||
// Expose functions to global scope for inline event handlers
|
||||
window.toggleTask = toggleTask;
|
||||
window.deleteTask = deleteTask;
|
||||
});`,
|
||||
"javascript",
|
||||
"app.js",
|
||||
},
|
||||
}
|
||||
|
||||
// Create a consistent style for the project files
|
||||
freeze := freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("Cascadia Code", 13).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(10, 0, 5).
|
||||
WithPadding(20)
|
||||
|
||||
for _, file := range projectFiles {
|
||||
fmt.Printf("📄 Generating %s file (%s)...\n", file.name, file.filename)
|
||||
|
||||
svgData, err := freeze.GenerateFromCode(file.code, file.lang)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error with %s: %v\n", file.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/project_%s.svg", file.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving %s: %v\n", filename, err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s\n", filename)
|
||||
}
|
||||
}
|
||||
|
||||
// Language-specific features example
|
||||
func languageSpecificFeaturesExample() {
|
||||
fmt.Println("\n✨ Language-Specific Features")
|
||||
fmt.Println("----------------------------")
|
||||
|
||||
// Language-specific code features
|
||||
features := []struct {
|
||||
name string
|
||||
code string
|
||||
lang string
|
||||
description string
|
||||
}{
|
||||
{
|
||||
"go_concurrency",
|
||||
`package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
for j := range jobs {
|
||||
fmt.Printf("Worker %d started job %d\n", id, j)
|
||||
time.Sleep(time.Second) // Simulate work
|
||||
fmt.Printf("Worker %d finished job %d\n", id, j)
|
||||
results <- j * 2
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
jobs := make(chan int, 5)
|
||||
results := make(chan int, 5)
|
||||
|
||||
// Start workers
|
||||
var wg sync.WaitGroup
|
||||
for w := 1; w <= 3; w++ {
|
||||
wg.Add(1)
|
||||
go worker(w, jobs, results, &wg)
|
||||
}
|
||||
|
||||
// Send jobs
|
||||
for j := 1; j <= 5; j++ {
|
||||
jobs <- j
|
||||
}
|
||||
close(jobs)
|
||||
|
||||
// Wait for workers to finish
|
||||
wg.Wait()
|
||||
close(results)
|
||||
|
||||
// Collect results
|
||||
for r := range results {
|
||||
fmt.Println("Result:", r)
|
||||
}
|
||||
}`,
|
||||
"go",
|
||||
"Go Concurrency with Goroutines and Channels",
|
||||
},
|
||||
{
|
||||
"python_decorators",
|
||||
`import time
|
||||
import functools
|
||||
from typing import Callable, TypeVar, Any
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
def timer(func: Callable[..., T]) -> Callable[..., T]:
|
||||
"""Decorator that prints the execution time of a function."""
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args: Any, **kwargs: Any) -> T:
|
||||
start_time = time.time()
|
||||
result = func(*args, **kwargs)
|
||||
end_time = time.time()
|
||||
print(f"{func.__name__} executed in {end_time - start_time:.4f} seconds")
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
def memoize(func: Callable[..., T]) -> Callable[..., T]:
|
||||
"""Decorator that caches function results."""
|
||||
cache = {}
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args: Any, **kwargs: Any) -> T:
|
||||
key = str(args) + str(kwargs)
|
||||
if key not in cache:
|
||||
cache[key] = func(*args, **kwargs)
|
||||
return cache[key]
|
||||
return wrapper
|
||||
|
||||
@timer
|
||||
@memoize
|
||||
def fibonacci(n: int) -> int:
|
||||
"""Calculate the nth Fibonacci number."""
|
||||
if n <= 1:
|
||||
return n
|
||||
return fibonacci(n-1) + fibonacci(n-2)
|
||||
|
||||
# Test the decorated function
|
||||
print(fibonacci(30)) # First call will be timed
|
||||
print(fibonacci(30)) # Second call will use cached result`,
|
||||
"python",
|
||||
"Python Decorators and Type Annotations",
|
||||
},
|
||||
{
|
||||
"typescript_generics",
|
||||
`// TypeScript Generics and Interfaces
|
||||
interface Repository<T> {
|
||||
getById(id: string): Promise<T>;
|
||||
getAll(): Promise<T[]>;
|
||||
create(item: T): Promise<T>;
|
||||
update(id: string, item: T): Promise<T>;
|
||||
delete(id: string): Promise<boolean>;
|
||||
}
|
||||
|
||||
interface User {
|
||||
id?: string;
|
||||
name: string;
|
||||
email: string;
|
||||
role: 'admin' | 'user' | 'guest';
|
||||
createdAt?: Date;
|
||||
}
|
||||
|
||||
class UserRepository implements Repository<User> {
|
||||
private users: Map<string, User> = new Map();
|
||||
|
||||
async getById(id: string): Promise<User> {
|
||||
const user = this.users.get(id);
|
||||
if (!user) {
|
||||
throw new Error(User with id ${id} not found);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
async getAll(): Promise<User[]> {
|
||||
return Array.from(this.users.values());
|
||||
}
|
||||
|
||||
async create(user: User): Promise<User> {
|
||||
const id = Math.random().toString(36).substring(2, 9);
|
||||
const newUser = {
|
||||
...user,
|
||||
id,
|
||||
createdAt: new Date()
|
||||
};
|
||||
this.users.set(id, newUser);
|
||||
return newUser;
|
||||
}
|
||||
|
||||
async update(id: string, user: User): Promise<User> {
|
||||
if (!this.users.has(id)) {
|
||||
throw new Error('User with id ${id} not found');
|
||||
}
|
||||
const updatedUser = { ...user, id };
|
||||
this.users.set(id, updatedUser);
|
||||
return updatedUser;
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<boolean> {
|
||||
return this.users.delete(id);
|
||||
}
|
||||
}
|
||||
|
||||
// Usage example
|
||||
async function main() {
|
||||
const userRepo = new UserRepository();
|
||||
|
||||
const newUser = await userRepo.create({
|
||||
name: 'John Doe',
|
||||
email: 'john@example.com',
|
||||
role: 'admin'
|
||||
});
|
||||
|
||||
console.log('Created user:', newUser);
|
||||
|
||||
const allUsers = await userRepo.getAll();
|
||||
console.log('All users:', allUsers);
|
||||
}
|
||||
|
||||
main().catch(console.error);`,
|
||||
"typescript",
|
||||
"TypeScript Generics, Interfaces and Type Safety",
|
||||
},
|
||||
}
|
||||
|
||||
// Create a consistent style for the feature examples
|
||||
freeze := freezelib.New().
|
||||
WithTheme("one-dark").
|
||||
WithFont("JetBrains Mono", 13).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(15, 0, 8).
|
||||
WithPadding(20)
|
||||
|
||||
for _, feature := range features {
|
||||
fmt.Printf("🔍 Generating %s example...\n", feature.name)
|
||||
|
||||
svgData, err := freeze.GenerateFromCode(feature.code, feature.lang)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error with %s: %v\n", feature.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/feature_%s.svg", feature.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving %s: %v\n", filename, err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s - %s\n", filename, feature.description)
|
||||
}
|
||||
}
|
411
examples/05-terminal/main.go
Normal file
411
examples/05-terminal/main.go
Normal file
@@ -0,0 +1,411 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/landaiqing/freezelib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("💻 Terminal Output Examples")
|
||||
fmt.Println("============================")
|
||||
|
||||
// Create output directory
|
||||
os.MkdirAll("output", 0755)
|
||||
|
||||
// Run terminal examples
|
||||
basicAnsiExample()
|
||||
buildOutputExample()
|
||||
testResultsExample()
|
||||
dockerOutputExample()
|
||||
gitOutputExample()
|
||||
systemLogsExample()
|
||||
|
||||
fmt.Println("\n✅ Terminal examples completed!")
|
||||
fmt.Println("📁 Check the 'output' directory for generated files.")
|
||||
}
|
||||
|
||||
// Basic ANSI color example
|
||||
func basicAnsiExample() {
|
||||
fmt.Println("\n🌈 Basic ANSI Colors")
|
||||
fmt.Println("--------------------")
|
||||
|
||||
// Terminal preset optimized for ANSI output
|
||||
freeze := freezelib.NewWithPreset("terminal")
|
||||
|
||||
ansiOutput := `\033[32m✓ SUCCESS\033[0m: Application started successfully
|
||||
\033[33m⚠ WARNING\033[0m: Configuration file not found, using defaults
|
||||
\033[31m✗ ERROR\033[0m: Failed to connect to database
|
||||
\033[36mINFO\033[0m: Server listening on port 8080
|
||||
\033[35mDEBUG\033[0m: Loading user preferences
|
||||
\033[37mTRACE\033[0m: Function call: getUserById(123)
|
||||
|
||||
\033[1mBold text\033[0m and \033[4munderlined text\033[0m
|
||||
\033[7mReversed text\033[0m and \033[9mstrikethrough text\033[0m
|
||||
|
||||
Background colors:
|
||||
\033[41mRed background\033[0m
|
||||
\033[42mGreen background\033[0m
|
||||
\033[43mYellow background\033[0m
|
||||
\033[44mBlue background\033[0m`
|
||||
|
||||
svgData, err := freeze.GenerateFromANSI(ansiOutput)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile("output/basic_ansi.svg", svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("✅ Generated: output/basic_ansi.svg")
|
||||
}
|
||||
|
||||
// Build output example
|
||||
func buildOutputExample() {
|
||||
fmt.Println("\n🔨 Build Output")
|
||||
fmt.Println("---------------")
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme("github-dark").
|
||||
WithFont("Cascadia Code", 13).
|
||||
WithWindow(true).
|
||||
WithPadding(20).
|
||||
WithBackground("#0d1117")
|
||||
|
||||
buildOutput := `$ go build -v ./...
|
||||
github.com/myproject/internal/config
|
||||
github.com/myproject/internal/database
|
||||
github.com/myproject/internal/handlers
|
||||
github.com/myproject/cmd/server
|
||||
|
||||
\033[32m✓ Build completed successfully\033[0m
|
||||
|
||||
$ go test -v ./...
|
||||
=== RUN TestUserService_CreateUser
|
||||
--- PASS: TestUserService_CreateUser (0.01s)
|
||||
=== RUN TestUserService_GetUser
|
||||
--- PASS: TestUserService_GetUser (0.00s)
|
||||
=== RUN TestUserService_UpdateUser
|
||||
--- PASS: TestUserService_UpdateUser (0.01s)
|
||||
=== RUN TestUserService_DeleteUser
|
||||
--- PASS: TestUserService_DeleteUser (0.00s)
|
||||
=== RUN TestDatabaseConnection
|
||||
--- PASS: TestDatabaseConnection (0.05s)
|
||||
|
||||
\033[32mPASS\033[0m
|
||||
\033[32mok \033[0m github.com/myproject 0.123s
|
||||
|
||||
\033[36mCoverage: 85.7% of statements\033[0m
|
||||
|
||||
$ docker build -t myapp:latest .
|
||||
Sending build context to Docker daemon 2.048kB
|
||||
Step 1/8 : FROM golang:1.21-alpine AS builder
|
||||
---> 7642119cd161
|
||||
Step 2/8 : WORKDIR /app
|
||||
---> Using cache
|
||||
---> 8f3b8c9d4e5f
|
||||
Step 3/8 : COPY go.mod go.sum ./
|
||||
---> Using cache
|
||||
---> 1a2b3c4d5e6f
|
||||
Step 4/8 : RUN go mod download
|
||||
---> Using cache
|
||||
---> 2b3c4d5e6f7g
|
||||
Step 5/8 : COPY . .
|
||||
---> 3c4d5e6f7g8h
|
||||
Step 6/8 : RUN go build -o main .
|
||||
---> Running in 4d5e6f7g8h9i
|
||||
---> 5e6f7g8h9i0j
|
||||
Step 7/8 : FROM alpine:latest
|
||||
---> 6f7g8h9i0j1k
|
||||
Step 8/8 : COPY --from=builder /app/main /main
|
||||
---> 7g8h9i0j1k2l
|
||||
\033[32mSuccessfully built 7g8h9i0j1k2l\033[0m
|
||||
\033[32mSuccessfully tagged myapp:latest\033[0m`
|
||||
|
||||
svgData, err := freeze.GenerateFromANSI(buildOutput)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile("output/build_output.svg", svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("✅ Generated: output/build_output.svg")
|
||||
}
|
||||
|
||||
// Test results example
|
||||
func testResultsExample() {
|
||||
fmt.Println("\n🧪 Test Results")
|
||||
fmt.Println("---------------")
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme("dracula").
|
||||
WithFont("JetBrains Mono", 14).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(false).
|
||||
WithShadow(15, 0, 10).
|
||||
WithPadding(25)
|
||||
|
||||
testOutput := `$ npm test
|
||||
|
||||
> myapp@1.0.0 test
|
||||
> jest --coverage
|
||||
|
||||
PASS src/components/Button.test.js
|
||||
Button Component
|
||||
\033[32m✓\033[0m renders correctly (15ms)
|
||||
\033[32m✓\033[0m handles click events (8ms)
|
||||
\033[32m✓\033[0m applies custom className (3ms)
|
||||
|
||||
PASS src/services/api.test.js
|
||||
API Service
|
||||
\033[32m✓\033[0m fetches user data (45ms)
|
||||
\033[32m✓\033[0m handles network errors (12ms)
|
||||
\033[32m✓\033[0m retries failed requests (23ms)
|
||||
|
||||
FAIL src/utils/validation.test.js
|
||||
Validation Utils
|
||||
\033[32m✓\033[0m validates email addresses (5ms)
|
||||
\033[31m✗\033[0m validates phone numbers (8ms)
|
||||
\033[32m✓\033[0m validates passwords (3ms)
|
||||
|
||||
● Validation Utils › validates phone numbers
|
||||
|
||||
expect(received).toBe(expected)
|
||||
|
||||
Expected: true
|
||||
Received: false
|
||||
|
||||
12 | test('validates phone numbers', () => {
|
||||
13 | const phoneNumber = '+1-555-123-4567';
|
||||
> 14 | expect(isValidPhoneNumber(phoneNumber)).toBe(true);
|
||||
| ^
|
||||
15 | });
|
||||
|
||||
at Object.<anonymous> (src/utils/validation.test.js:14:45)
|
||||
|
||||
\033[33mTest Suites: 1 failed, 2 passed, 3 total\033[0m
|
||||
\033[33mTests: 1 failed, 7 passed, 8 total\033[0m
|
||||
\033[33mSnapshots: 0 total\033[0m
|
||||
\033[33mTime: 2.847s\033[0m
|
||||
|
||||
\033[36m----------------------|---------|----------|---------|---------|-------------------\033[0m
|
||||
\033[36mFile | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s\033[0m
|
||||
\033[36m----------------------|---------|----------|---------|---------|-------------------\033[0m
|
||||
\033[36mAll files | 87.5 | 75.0 | 90.0 | 87.5 |\033[0m
|
||||
\033[36m src/components | 95.0 | 85.0 | 100.0 | 95.0 |\033[0m
|
||||
\033[36m Button.js | 95.0 | 85.0 | 100.0 | 95.0 | 23\033[0m
|
||||
\033[36m src/services | 80.0 | 65.0 | 80.0 | 80.0 |\033[0m
|
||||
\033[36m api.js | 80.0 | 65.0 | 80.0 | 80.0 | 45,67\033[0m
|
||||
\033[36m src/utils | 87.5 | 75.0 | 90.0 | 87.5 |\033[0m
|
||||
\033[36m validation.js | 87.5 | 75.0 | 90.0 | 87.5 | 34\033[0m
|
||||
\033[36m----------------------|---------|----------|---------|---------|-------------------\033[0m`
|
||||
|
||||
svgData, err := freeze.GenerateFromANSI(testOutput)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile("output/test_results.svg", svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("✅ Generated: output/test_results.svg")
|
||||
}
|
||||
|
||||
// Docker output example
|
||||
func dockerOutputExample() {
|
||||
fmt.Println("\n🐳 Docker Output")
|
||||
fmt.Println("----------------")
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme("nord").
|
||||
WithFont("SF Mono", 13).
|
||||
WithWindow(true).
|
||||
WithPadding(20).
|
||||
WithBackground("#2e3440")
|
||||
|
||||
dockerOutput := `$ docker-compose up -d
|
||||
Creating network "myapp_default" with the default driver
|
||||
Creating volume "myapp_postgres_data" with default driver
|
||||
Creating volume "myapp_redis_data" with default driver
|
||||
|
||||
\033[33mPulling postgres (postgres:13)...\033[0m
|
||||
13: Pulling from library/postgres
|
||||
\033[36m7b1a6ab2e44d\033[0m: Pull complete
|
||||
\033[36m5c9d4e5f6a7b\033[0m: Pull complete
|
||||
\033[36m8c1d2e3f4a5b\033[0m: Pull complete
|
||||
\033[36m9d2e3f4a5b6c\033[0m: Pull complete
|
||||
\033[32mDigest: sha256:abc123def456...\033[0m
|
||||
\033[32mStatus: Downloaded newer image for postgres:13\033[0m
|
||||
|
||||
\033[33mPulling redis (redis:6-alpine)...\033[0m
|
||||
6-alpine: Pulling from library/redis
|
||||
\033[36m4c0d5e6f7a8b\033[0m: Pull complete
|
||||
\033[36m5d1e6f7a8b9c\033[0m: Pull complete
|
||||
\033[32mDigest: sha256:def456ghi789...\033[0m
|
||||
\033[32mStatus: Downloaded newer image for redis:6-alpine\033[0m
|
||||
|
||||
Creating myapp_postgres_1 ... \033[32mdone\033[0m
|
||||
Creating myapp_redis_1 ... \033[32mdone\033[0m
|
||||
Creating myapp_web_1 ... \033[32mdone\033[0m
|
||||
|
||||
$ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
\033[36m1a2b3c4d5e6f\033[0m myapp:latest "go run main.go" 2 minutes ago Up 2 minutes \033[35m0.0.0.0:8080->8080/tcp\033[0m myapp_web_1
|
||||
\033[36m2b3c4d5e6f7g\033[0m postgres:13 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes \033[35m5432/tcp\033[0m myapp_postgres_1
|
||||
\033[36m3c4d5e6f7g8h\033[0m redis:6-alpine "docker-entrypoint.s…" 2 minutes ago Up 2 minutes \033[35m6379/tcp\033[0m myapp_redis_1
|
||||
|
||||
$ docker logs myapp_web_1
|
||||
\033[36m2024/01/15 10:30:00\033[0m \033[32mINFO\033[0m Starting server...
|
||||
\033[36m2024/01/15 10:30:00\033[0m \033[32mINFO\033[0m Connected to database
|
||||
\033[36m2024/01/15 10:30:00\033[0m \033[32mINFO\033[0m Connected to Redis
|
||||
\033[36m2024/01/15 10:30:00\033[0m \033[32mINFO\033[0m Server listening on :8080
|
||||
\033[36m2024/01/15 10:30:15\033[0m \033[36mDEBUG\033[0m GET /api/health - 200 OK (2ms)
|
||||
\033[36m2024/01/15 10:30:20\033[0m \033[36mDEBUG\033[0m POST /api/users - 201 Created (45ms)`
|
||||
|
||||
svgData, err := freeze.GenerateFromANSI(dockerOutput)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile("output/docker_output.svg", svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("✅ Generated: output/docker_output.svg")
|
||||
}
|
||||
|
||||
// Git output example
|
||||
func gitOutputExample() {
|
||||
fmt.Println("\n📚 Git Output")
|
||||
fmt.Println("-------------")
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("Menlo", 13).
|
||||
WithWindow(true).
|
||||
WithPadding(20).
|
||||
WithBackground("#ffffff")
|
||||
|
||||
gitOutput := `$ git status
|
||||
On branch feature/user-authentication
|
||||
Your branch is ahead of 'origin/main' by 3 commits.
|
||||
(use "git push" to publish your local commits)
|
||||
|
||||
Changes to be committed:
|
||||
(use "git restore --staged <file>..." to unstage)
|
||||
\033[32mnew file: src/auth/login.js\033[0m
|
||||
\033[32mnew file: src/auth/register.js\033[0m
|
||||
\033[32mmodified: src/app.js\033[0m
|
||||
\033[32mmodified: package.json\033[0m
|
||||
|
||||
Changes not staged for commit:
|
||||
(use "git add <file>..." to update what will be committed)
|
||||
(use "git restore <file>..." to discard changes in working directory)
|
||||
\033[31mmodified: README.md\033[0m
|
||||
\033[31mmodified: src/components/Header.js\033[0m
|
||||
|
||||
Untracked files:
|
||||
(use "git add <file>..." to include in what will be committed)
|
||||
\033[31msrc/auth/middleware.js\033[0m
|
||||
\033[31mtests/auth.test.js\033[0m
|
||||
|
||||
$ git log --oneline -5
|
||||
\033[33m7a8b9c0\033[0m \033[32m(HEAD -> feature/user-authentication)\033[0m Add user registration functionality
|
||||
\033[33m6a7b8c9\033[0m Add login form validation
|
||||
\033[33m5a6b7c8\033[0m Implement JWT authentication
|
||||
\033[33m4a5b6c7\033[0m \033[36m(origin/main, main)\033[0m Update project dependencies
|
||||
\033[33m3a4b5c6\033[0m Fix responsive design issues
|
||||
|
||||
$ git diff --stat
|
||||
README.md | 15 \033[32m+++++++++\033[0m\033[31m------\033[0m
|
||||
package.json | 3 \033[32m+++\033[0m
|
||||
src/app.js | 42 \033[32m++++++++++++++++++++++++++++++\033[0m\033[31m----------\033[0m
|
||||
src/auth/login.js | 67 \033[32m+++++++++++++++++++++++++++++++++++++++++++++++++++++++\033[0m
|
||||
src/auth/register.js | 89 \033[32m++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\033[0m
|
||||
src/components/Header.js | 8 \033[32m+++++\033[0m\033[31m---\033[0m
|
||||
6 files changed, 201 insertions(+), 23 deletions(-)`
|
||||
|
||||
svgData, err := freeze.GenerateFromANSI(gitOutput)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile("output/git_output.svg", svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("✅ Generated: output/git_output.svg")
|
||||
}
|
||||
|
||||
// System logs example
|
||||
func systemLogsExample() {
|
||||
fmt.Println("\n📋 System Logs")
|
||||
fmt.Println("--------------")
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme("monokai").
|
||||
WithFont("Ubuntu Mono", 13).
|
||||
WithWindow(true).
|
||||
WithPadding(20).
|
||||
WithBackground("#272822")
|
||||
|
||||
systemLogs := `$ tail -f /var/log/application.log
|
||||
|
||||
\033[90m2024-01-15 10:30:00.123\033[0m [\033[32mINFO \033[0m] \033[36mApplication\033[0m - Server starting up
|
||||
\033[90m2024-01-15 10:30:00.456\033[0m [\033[32mINFO \033[0m] \033[36mDatabase \033[0m - Connection pool initialized (size: 10)
|
||||
\033[90m2024-01-15 10:30:00.789\033[0m [\033[32mINFO \033[0m] \033[36mCache \033[0m - Redis connection established
|
||||
\033[90m2024-01-15 10:30:01.012\033[0m [\033[32mINFO \033[0m] \033[36mSecurity \033[0m - JWT secret loaded from environment
|
||||
\033[90m2024-01-15 10:30:01.234\033[0m [\033[32mINFO \033[0m] \033[36mHTTP \033[0m - Server listening on port 8080
|
||||
|
||||
\033[90m2024-01-15 10:30:15.567\033[0m [\033[34mDEBUG\033[0m] \033[36mAuth \033[0m - User login attempt: user@example.com
|
||||
\033[90m2024-01-15 10:30:15.678\033[0m [\033[32mINFO \033[0m] \033[36mAuth \033[0m - User authenticated successfully: user@example.com
|
||||
\033[90m2024-01-15 10:30:15.789\033[0m [\033[34mDEBUG\033[0m] \033[36mHTTP \033[0m - POST /api/auth/login - 200 OK (223ms)
|
||||
|
||||
\033[90m2024-01-15 10:30:30.123\033[0m [\033[33mWARN \033[0m] \033[36mDatabase \033[0m - Slow query detected (1.2s): SELECT * FROM users WHERE...
|
||||
\033[90m2024-01-15 10:30:30.234\033[0m [\033[34mDEBUG\033[0m] \033[36mHTTP \033[0m - GET /api/users - 200 OK (1234ms)
|
||||
|
||||
\033[90m2024-01-15 10:30:45.456\033[0m [\033[31mERROR\033[0m] \033[36mPayment \033[0m - Payment processing failed: insufficient funds
|
||||
\033[90m2024-01-15 10:30:45.567\033[0m [\033[31mERROR\033[0m] \033[36mPayment \033[0m - Stack trace:
|
||||
at PaymentService.processPayment (payment.js:45:12)
|
||||
at OrderController.createOrder (order.js:23:8)
|
||||
at Router.handle (express.js:123:5)
|
||||
\033[90m2024-01-15 10:30:45.678\033[0m [\033[34mDEBUG\033[0m] \033[36mHTTP \033[0m - POST /api/orders - 400 Bad Request (112ms)
|
||||
|
||||
\033[90m2024-01-15 10:31:00.789\033[0m [\033[32mINFO \033[0m] \033[36mScheduler\033[0m - Running daily cleanup task
|
||||
\033[90m2024-01-15 10:31:05.012\033[0m [\033[32mINFO \033[0m] \033[36mScheduler\033[0m - Cleanup completed: removed 1,234 expired sessions
|
||||
\033[90m2024-01-15 10:31:05.123\033[0m [\033[32mINFO \033[0m] \033[36mScheduler\033[0m - Next cleanup scheduled for 2024-01-16 10:31:00`
|
||||
|
||||
svgData, err := freeze.GenerateFromANSI(systemLogs)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile("output/system_logs.svg", svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("✅ Generated: output/system_logs.svg")
|
||||
}
|
587
examples/06-advanced/main.go
Normal file
587
examples/06-advanced/main.go
Normal file
@@ -0,0 +1,587 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/landaiqing/freezelib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("🔧 Advanced Configuration Examples")
|
||||
fmt.Println("===================================")
|
||||
|
||||
// Create output directory
|
||||
os.MkdirAll("output", 0755)
|
||||
|
||||
// Run advanced examples
|
||||
customFontExample()
|
||||
advancedLayoutExample()
|
||||
performanceOptimizationExample()
|
||||
responsiveDesignExample()
|
||||
brandingExample()
|
||||
|
||||
fmt.Println("\n✅ Advanced examples completed!")
|
||||
fmt.Println("📁 Check the 'output' directory for generated files.")
|
||||
}
|
||||
|
||||
// Custom font example
|
||||
func customFontExample() {
|
||||
fmt.Println("\n🔤 Custom Font Examples")
|
||||
fmt.Println("-----------------------")
|
||||
|
||||
code := `interface UserRepository {
|
||||
findById(id: string): Promise<User | null>;
|
||||
findByEmail(email: string): Promise<User | null>;
|
||||
create(user: CreateUserDto): Promise<User>;
|
||||
update(id: string, updates: UpdateUserDto): Promise<User>;
|
||||
delete(id: string): Promise<void>;
|
||||
}
|
||||
|
||||
class PostgresUserRepository implements UserRepository {
|
||||
constructor(private db: Database) {}
|
||||
|
||||
async findById(id: string): Promise<User | null> {
|
||||
const result = await this.db.query(
|
||||
'SELECT * FROM users WHERE id = $1',
|
||||
[id]
|
||||
);
|
||||
return result.rows[0] || null;
|
||||
}
|
||||
|
||||
async create(user: CreateUserDto): Promise<User> {
|
||||
const { name, email, role } = user;
|
||||
const result = await this.db.query(
|
||||
'INSERT INTO users (name, email, role) VALUES ($1, $2, $3) RETURNING *',
|
||||
[name, email, role]
|
||||
);
|
||||
return result.rows[0];
|
||||
}
|
||||
}`
|
||||
|
||||
// Different font configurations
|
||||
fontConfigs := []struct {
|
||||
name string
|
||||
family string
|
||||
size float64
|
||||
desc string
|
||||
}{
|
||||
{"monospace_small", "Courier New", 12, "Small monospace font"},
|
||||
{"monospace_large", "JetBrains Mono", 16, "Large modern monospace"},
|
||||
{"system_font", "system-ui", 14, "System default font"},
|
||||
{"serif_font", "Georgia", 14, "Serif font for readability"},
|
||||
{"condensed_font", "SF Mono", 13, "Condensed font for more content"},
|
||||
}
|
||||
|
||||
for _, config := range fontConfigs {
|
||||
fmt.Printf("🔤 Generating %s example...\n", config.name)
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme("github-dark").
|
||||
WithFont(config.family, config.size).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(15, 0, 8).
|
||||
WithPadding(25)
|
||||
|
||||
svgData, err := freeze.GenerateFromCode(code, "typescript")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/font_%s.svg", config.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s - %s\n", filename, config.desc)
|
||||
}
|
||||
}
|
||||
|
||||
// Advanced layout example
|
||||
func advancedLayoutExample() {
|
||||
fmt.Println("\n📐 Advanced Layout Examples")
|
||||
fmt.Println("---------------------------")
|
||||
|
||||
code := `from dataclasses import dataclass
|
||||
from typing import List, Optional, Dict, Any
|
||||
from datetime import datetime
|
||||
import asyncio
|
||||
import aiohttp
|
||||
|
||||
@dataclass
|
||||
class APIResponse:
|
||||
status_code: int
|
||||
data: Dict[str, Any]
|
||||
headers: Dict[str, str]
|
||||
timestamp: datetime
|
||||
|
||||
class AsyncAPIClient:
|
||||
def __init__(self, base_url: str, timeout: int = 30):
|
||||
self.base_url = base_url.rstrip('/')
|
||||
self.timeout = aiohttp.ClientTimeout(total=timeout)
|
||||
self.session: Optional[aiohttp.ClientSession] = None
|
||||
|
||||
async def __aenter__(self):
|
||||
self.session = aiohttp.ClientSession(timeout=self.timeout)
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
||||
if self.session:
|
||||
await self.session.close()
|
||||
|
||||
async def get(self, endpoint: str, params: Optional[Dict] = None) -> APIResponse:
|
||||
if not self.session:
|
||||
raise RuntimeError("Client not initialized. Use async context manager.")
|
||||
|
||||
url = f"{self.base_url}/{endpoint.lstrip('/')}"
|
||||
|
||||
async with self.session.get(url, params=params) as response:
|
||||
data = await response.json()
|
||||
return APIResponse(
|
||||
status_code=response.status,
|
||||
data=data,
|
||||
headers=dict(response.headers),
|
||||
timestamp=datetime.now()
|
||||
)
|
||||
|
||||
# Usage example
|
||||
async def main():
|
||||
async with AsyncAPIClient("https://api.example.com") as client:
|
||||
response = await client.get("/users", {"page": 1, "limit": 10})
|
||||
print(f"Status: {response.status_code}")
|
||||
print(f"Data: {response.data}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())`
|
||||
|
||||
// Different layout configurations
|
||||
layouts := []struct {
|
||||
name string
|
||||
config func() *freezelib.Freeze
|
||||
desc string
|
||||
}{
|
||||
{
|
||||
"compact",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("SF Mono", 11).
|
||||
WithPadding(10).
|
||||
WithMargin(5).
|
||||
WithWindow(false).
|
||||
WithLineNumbers(true).
|
||||
WithDimensions(600, 800)
|
||||
},
|
||||
"Compact layout for maximum content",
|
||||
},
|
||||
{
|
||||
"spacious",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("github-dark").
|
||||
WithFont("JetBrains Mono", 16).
|
||||
WithPadding(40).
|
||||
WithMargin(30).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(25, 0, 15).
|
||||
WithDimensions(1000, 1200)
|
||||
},
|
||||
"Spacious layout for presentations",
|
||||
},
|
||||
{
|
||||
"mobile_friendly",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("dracula").
|
||||
WithFont("Menlo", 13).
|
||||
WithPadding(15).
|
||||
WithMargin(10).
|
||||
WithWindow(false).
|
||||
WithLineNumbers(false).
|
||||
WithDimensions(400, 600)
|
||||
},
|
||||
"Mobile-friendly narrow layout",
|
||||
},
|
||||
{
|
||||
"print_optimized",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("Times New Roman", 12).
|
||||
WithPadding(20).
|
||||
WithMargin(15).
|
||||
WithWindow(false).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(0, 0, 0). // No shadow for print
|
||||
WithBackground("#ffffff").
|
||||
WithDimensions(800, 1000)
|
||||
},
|
||||
"Print-optimized layout",
|
||||
},
|
||||
}
|
||||
|
||||
for _, layout := range layouts {
|
||||
fmt.Printf("📐 Creating %s layout...\n", layout.name)
|
||||
|
||||
freeze := layout.config()
|
||||
svgData, err := freeze.GenerateFromCode(code, "python")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/layout_%s.svg", layout.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s - %s\n", filename, layout.desc)
|
||||
}
|
||||
}
|
||||
|
||||
// Performance optimization example
|
||||
func performanceOptimizationExample() {
|
||||
fmt.Println("\n⚡ Performance Optimization")
|
||||
fmt.Println("---------------------------")
|
||||
|
||||
// Short code for performance testing
|
||||
shortCode := `fn quicksort<T: Ord>(arr: &mut [T]) {
|
||||
if arr.len() <= 1 {
|
||||
return;
|
||||
}
|
||||
|
||||
let pivot_index = partition(arr);
|
||||
let (left, right) = arr.split_at_mut(pivot_index);
|
||||
|
||||
quicksort(left);
|
||||
quicksort(&mut right[1..]);
|
||||
}
|
||||
|
||||
fn partition<T: Ord>(arr: &mut [T]) -> usize {
|
||||
let pivot_index = arr.len() - 1;
|
||||
let mut i = 0;
|
||||
|
||||
for j in 0..pivot_index {
|
||||
if arr[j] <= arr[pivot_index] {
|
||||
arr.swap(i, j);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
arr.swap(i, pivot_index);
|
||||
i
|
||||
}`
|
||||
|
||||
// Performance-optimized configurations
|
||||
perfConfigs := []struct {
|
||||
name string
|
||||
config func() *freezelib.Freeze
|
||||
desc string
|
||||
}{
|
||||
{
|
||||
"minimal_overhead",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("monospace", 12).
|
||||
WithWindow(false).
|
||||
WithLineNumbers(false).
|
||||
WithShadow(0, 0, 0).
|
||||
WithPadding(10).
|
||||
WithMargin(0)
|
||||
},
|
||||
"Minimal processing overhead",
|
||||
},
|
||||
{
|
||||
"optimized_svg",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("system-ui", 13).
|
||||
WithWindow(false).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(0, 0, 0).
|
||||
WithPadding(15).
|
||||
WithDimensions(600, 400) // Fixed dimensions
|
||||
},
|
||||
"SVG-optimized configuration",
|
||||
},
|
||||
{
|
||||
"batch_processing",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("monokai").
|
||||
WithFont("Courier", 12).
|
||||
WithWindow(false).
|
||||
WithLineNumbers(false).
|
||||
WithPadding(12).
|
||||
WithDimensions(500, 300)
|
||||
},
|
||||
"Optimized for batch processing",
|
||||
},
|
||||
}
|
||||
|
||||
for _, config := range perfConfigs {
|
||||
fmt.Printf("⚡ Testing %s...\n", config.name)
|
||||
|
||||
freeze := config.config()
|
||||
|
||||
// Generate multiple times to test performance
|
||||
for i := 0; i < 3; i++ {
|
||||
svgData, err := freeze.GenerateFromCode(shortCode, "rust")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
break
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/perf_%s_%d.svg", config.name, i+1)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving: %v\n", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated 3 files for %s - %s\n", config.name, config.desc)
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive design example
|
||||
func responsiveDesignExample() {
|
||||
fmt.Println("\n📱 Responsive Design")
|
||||
fmt.Println("--------------------")
|
||||
|
||||
code := `@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.navigation {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 769px) and (max-width: 1024px) {
|
||||
.container {
|
||||
max-width: 750px;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1025px) {
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
padding: 3rem;
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.hero {
|
||||
height: 60vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}`
|
||||
|
||||
// Different screen size simulations
|
||||
screenSizes := []struct {
|
||||
name string
|
||||
width float64
|
||||
height float64
|
||||
desc string
|
||||
}{
|
||||
{"mobile", 375, 600, "Mobile phone size"},
|
||||
{"tablet", 768, 800, "Tablet size"},
|
||||
{"desktop", 1200, 800, "Desktop size"},
|
||||
{"ultrawide", 1600, 900, "Ultrawide monitor"},
|
||||
}
|
||||
|
||||
for _, size := range screenSizes {
|
||||
fmt.Printf("📱 Creating %s responsive example...\n", size.name)
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("system-ui", 13).
|
||||
WithDimensions(size.width, size.height).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithPadding(20).
|
||||
WithShadow(10, 0, 5)
|
||||
|
||||
svgData, err := freeze.GenerateFromCode(code, "css")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/responsive_%s.svg", size.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s (%dx%d) - %s\n",
|
||||
filename, size.width, size.height, size.desc)
|
||||
}
|
||||
}
|
||||
|
||||
// Branding example
|
||||
func brandingExample() {
|
||||
fmt.Println("\n🎨 Branding Examples")
|
||||
fmt.Println("--------------------")
|
||||
|
||||
code := `public class BrandService {
|
||||
private final Logger logger = LoggerFactory.getLogger(BrandService.class);
|
||||
private final BrandRepository brandRepository;
|
||||
private final CacheManager cacheManager;
|
||||
|
||||
public BrandService(BrandRepository brandRepository, CacheManager cacheManager) {
|
||||
this.brandRepository = brandRepository;
|
||||
this.cacheManager = cacheManager;
|
||||
}
|
||||
|
||||
@Cacheable("brands")
|
||||
public Brand getBrandById(Long id) {
|
||||
logger.info("Fetching brand with id: {}", id);
|
||||
|
||||
return brandRepository.findById(id)
|
||||
.orElseThrow(() -> new BrandNotFoundException("Brand not found: " + id));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Brand createBrand(CreateBrandRequest request) {
|
||||
validateBrandRequest(request);
|
||||
|
||||
Brand brand = Brand.builder()
|
||||
.name(request.getName())
|
||||
.description(request.getDescription())
|
||||
.logoUrl(request.getLogoUrl())
|
||||
.primaryColor(request.getPrimaryColor())
|
||||
.secondaryColor(request.getSecondaryColor())
|
||||
.createdAt(Instant.now())
|
||||
.build();
|
||||
|
||||
Brand savedBrand = brandRepository.save(brand);
|
||||
cacheManager.evictCache("brands");
|
||||
|
||||
logger.info("Created new brand: {}", savedBrand.getName());
|
||||
return savedBrand;
|
||||
}
|
||||
|
||||
private void validateBrandRequest(CreateBrandRequest request) {
|
||||
if (StringUtils.isBlank(request.getName())) {
|
||||
throw new ValidationException("Brand name is required");
|
||||
}
|
||||
|
||||
if (brandRepository.existsByName(request.getName())) {
|
||||
throw new ValidationException("Brand name already exists");
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
// Different brand styles
|
||||
brandStyles := []struct {
|
||||
name string
|
||||
config func() *freezelib.Freeze
|
||||
desc string
|
||||
}{
|
||||
{
|
||||
"corporate_blue",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("github").
|
||||
WithFont("Arial", 14).
|
||||
WithBackground("#f8f9fa").
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(8, 2, 4).
|
||||
WithBorder(2, 8, "#0066cc").
|
||||
WithPadding(30)
|
||||
},
|
||||
"Corporate blue branding",
|
||||
},
|
||||
{
|
||||
"startup_green",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("github-dark").
|
||||
WithFont("Inter", 14).
|
||||
WithBackground("#0d1117").
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(15, 0, 10).
|
||||
WithBorder(1, 12, "#00d084").
|
||||
WithPadding(25)
|
||||
},
|
||||
"Startup green branding",
|
||||
},
|
||||
{
|
||||
"creative_purple",
|
||||
func() *freezelib.Freeze {
|
||||
return freezelib.New().
|
||||
WithTheme("dracula").
|
||||
WithFont("Poppins", 14).
|
||||
WithBackground("#1a1a2e").
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(20, 0, 15).
|
||||
WithBorder(2, 16, "#8b5cf6").
|
||||
WithPadding(35)
|
||||
},
|
||||
"Creative purple branding",
|
||||
},
|
||||
}
|
||||
|
||||
for _, style := range brandStyles {
|
||||
fmt.Printf("🎨 Creating %s style...\n", style.name)
|
||||
|
||||
freeze := style.config()
|
||||
svgData, err := freeze.GenerateFromCode(code, "java")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/brand_%s.svg", style.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s - %s\n", filename, style.desc)
|
||||
}
|
||||
}
|
680
examples/07-batch/main.go
Normal file
680
examples/07-batch/main.go
Normal file
@@ -0,0 +1,680 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/landaiqing/freezelib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("📦 Batch Processing Examples")
|
||||
fmt.Println("=============================")
|
||||
|
||||
// Create output directory
|
||||
os.MkdirAll("output", 0755)
|
||||
os.MkdirAll("sample_files", 0755)
|
||||
|
||||
// Run batch examples
|
||||
createSampleFiles()
|
||||
batchFileProcessingExample()
|
||||
multiFormatBatchExample()
|
||||
concurrentProcessingExample()
|
||||
directoryProcessingExample()
|
||||
|
||||
fmt.Println("\n✅ Batch processing examples completed!")
|
||||
fmt.Println("📁 Check the 'output' directory for generated files.")
|
||||
}
|
||||
|
||||
// Create sample files for batch processing
|
||||
func createSampleFiles() {
|
||||
fmt.Println("\n📝 Creating Sample Files")
|
||||
fmt.Println("------------------------")
|
||||
|
||||
sampleFiles := map[string]string{
|
||||
"sample_files/main.go": `package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "Hello, World!")
|
||||
})
|
||||
|
||||
fmt.Println("Server starting on :8080")
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}`,
|
||||
|
||||
"sample_files/utils.py": `import json
|
||||
import logging
|
||||
from typing import Dict, List, Any, Optional
|
||||
from datetime import datetime
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def load_config(config_path: str) -> Dict[str, Any]:
|
||||
"""Load configuration from JSON file."""
|
||||
try:
|
||||
with open(config_path, 'r') as f:
|
||||
return json.load(f)
|
||||
except FileNotFoundError:
|
||||
logger.error(f"Config file not found: {config_path}")
|
||||
return {}
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"Invalid JSON in config file: {e}")
|
||||
return {}
|
||||
|
||||
def format_timestamp(timestamp: Optional[datetime] = None) -> str:
|
||||
"""Format timestamp to ISO string."""
|
||||
if timestamp is None:
|
||||
timestamp = datetime.now()
|
||||
return timestamp.isoformat()
|
||||
|
||||
class DataProcessor:
|
||||
def __init__(self, config: Dict[str, Any]):
|
||||
self.config = config
|
||||
self.processed_count = 0
|
||||
|
||||
def process_batch(self, items: List[Any]) -> List[Any]:
|
||||
"""Process a batch of items."""
|
||||
results = []
|
||||
for item in items:
|
||||
processed = self.process_item(item)
|
||||
if processed:
|
||||
results.append(processed)
|
||||
self.processed_count += 1
|
||||
return results
|
||||
|
||||
def process_item(self, item: Any) -> Optional[Any]:
|
||||
"""Process a single item."""
|
||||
# Implementation depends on item type
|
||||
return item`,
|
||||
|
||||
"sample_files/api.js": `const express = require('express');
|
||||
const cors = require('cors');
|
||||
const helmet = require('helmet');
|
||||
const rateLimit = require('express-rate-limit');
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3000;
|
||||
|
||||
// Middleware
|
||||
app.use(helmet());
|
||||
app.use(cors());
|
||||
app.use(express.json({ limit: '10mb' }));
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
|
||||
// Rate limiting
|
||||
const limiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 100, // limit each IP to 100 requests per windowMs
|
||||
message: 'Too many requests from this IP'
|
||||
});
|
||||
app.use('/api/', limiter);
|
||||
|
||||
// Routes
|
||||
app.get('/api/health', (req, res) => {
|
||||
res.json({
|
||||
status: 'healthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
uptime: process.uptime()
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/api/users', async (req, res) => {
|
||||
try {
|
||||
const { page = 1, limit = 10 } = req.query;
|
||||
const users = await getUsersPaginated(page, limit);
|
||||
|
||||
res.json({
|
||||
data: users,
|
||||
pagination: {
|
||||
page: parseInt(page),
|
||||
limit: parseInt(limit),
|
||||
total: await getTotalUsers()
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching users:', error);
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log('Server running on port \${PORT}\');
|
||||
});`,
|
||||
|
||||
"sample_files/styles.css": `/* Modern CSS Reset and Base Styles */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--primary-color: #3b82f6;
|
||||
--secondary-color: #64748b;
|
||||
--success-color: #10b981;
|
||||
--warning-color: #f59e0b;
|
||||
--error-color: #ef4444;
|
||||
--background-color: #ffffff;
|
||||
--surface-color: #f8fafc;
|
||||
--text-primary: #1e293b;
|
||||
--text-secondary: #64748b;
|
||||
--border-color: #e2e8f0;
|
||||
--shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background-color);
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--surface-color);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 8px;
|
||||
padding: 1.5rem;
|
||||
box-shadow: var(--shadow);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #2563eb;
|
||||
transform: translateY(-1px);
|
||||
}`,
|
||||
|
||||
"sample_files/config.json": `{
|
||||
"database": {
|
||||
"host": "localhost",
|
||||
"port": 5432,
|
||||
"name": "myapp",
|
||||
"user": "postgres",
|
||||
"password": "password",
|
||||
"ssl": false,
|
||||
"pool": {
|
||||
"min": 2,
|
||||
"max": 10,
|
||||
"idle_timeout": "30s"
|
||||
}
|
||||
},
|
||||
"redis": {
|
||||
"host": "localhost",
|
||||
"port": 6379,
|
||||
"password": "",
|
||||
"db": 0,
|
||||
"pool_size": 10
|
||||
},
|
||||
"server": {
|
||||
"host": "0.0.0.0",
|
||||
"port": 8080,
|
||||
"read_timeout": "30s",
|
||||
"write_timeout": "30s",
|
||||
"idle_timeout": "60s"
|
||||
},
|
||||
"logging": {
|
||||
"level": "info",
|
||||
"format": "json",
|
||||
"output": "stdout"
|
||||
},
|
||||
"features": {
|
||||
"enable_metrics": true,
|
||||
"enable_tracing": true,
|
||||
"enable_profiling": false
|
||||
}
|
||||
}`,
|
||||
}
|
||||
|
||||
for filename, content := range sampleFiles {
|
||||
err := os.WriteFile(filename, []byte(content), 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error creating %s: %v\n", filename, err)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("✅ Created: %s\n", filename)
|
||||
}
|
||||
}
|
||||
|
||||
// Batch file processing example
|
||||
func batchFileProcessingExample() {
|
||||
fmt.Println("\n📦 Batch File Processing")
|
||||
fmt.Println("------------------------")
|
||||
|
||||
// Get all sample files
|
||||
files, err := filepath.Glob("sample_files/*")
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error finding files: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Create a consistent freeze instance for all files
|
||||
freeze := freezelib.New().
|
||||
WithTheme("github-dark").
|
||||
WithFont("JetBrains Mono", 14).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(15, 0, 8).
|
||||
WithPadding(20)
|
||||
|
||||
fmt.Printf("🔄 Processing %d files...\n", len(files))
|
||||
|
||||
successCount := 0
|
||||
for _, file := range files {
|
||||
fmt.Printf("📄 Processing: %s\n", file)
|
||||
|
||||
// Detect language from file extension
|
||||
ext := filepath.Ext(file)
|
||||
lang := detectLanguage(ext)
|
||||
|
||||
svgData, err := freeze.GenerateFromFile(file)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error processing %s: %v\n", file, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Create output filename
|
||||
baseName := strings.TrimSuffix(filepath.Base(file), ext)
|
||||
outputFile := fmt.Sprintf("output/batch_%s.svg", baseName)
|
||||
|
||||
err = os.WriteFile(outputFile, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving %s: %v\n", outputFile, err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s (language: %s)\n", outputFile, lang)
|
||||
successCount++
|
||||
}
|
||||
|
||||
fmt.Printf("📊 Batch processing completed: %d/%d files successful\n",
|
||||
successCount, len(files))
|
||||
}
|
||||
|
||||
// Multi-format batch example
|
||||
func multiFormatBatchExample() {
|
||||
fmt.Println("\n🎨 Multi-format Batch Processing")
|
||||
fmt.Println("--------------------------------")
|
||||
|
||||
code := `#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
template<typename T>
|
||||
class SmartVector {
|
||||
private:
|
||||
std::unique_ptr<T[]> data;
|
||||
size_t size_;
|
||||
size_t capacity_;
|
||||
|
||||
public:
|
||||
SmartVector(size_t initial_capacity = 10)
|
||||
: data(std::make_unique<T[]>(initial_capacity))
|
||||
, size_(0)
|
||||
, capacity_(initial_capacity) {}
|
||||
|
||||
void push_back(const T& value) {
|
||||
if (size_ >= capacity_) {
|
||||
resize();
|
||||
}
|
||||
data[size_++] = value;
|
||||
}
|
||||
|
||||
T& operator[](size_t index) {
|
||||
if (index >= size_) {
|
||||
throw std::out_of_range("Index out of range");
|
||||
}
|
||||
return data[index];
|
||||
}
|
||||
|
||||
size_t size() const { return size_; }
|
||||
|
||||
void sort() {
|
||||
std::sort(data.get(), data.get() + size_);
|
||||
}
|
||||
|
||||
private:
|
||||
void resize() {
|
||||
capacity_ *= 2;
|
||||
auto new_data = std::make_unique<T[]>(capacity_);
|
||||
std::copy(data.get(), data.get() + size_, new_data.get());
|
||||
data = std::move(new_data);
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
SmartVector<int> vec;
|
||||
|
||||
for (int i = 0; i < 15; ++i) {
|
||||
vec.push_back(rand() % 100);
|
||||
}
|
||||
|
||||
vec.sort();
|
||||
|
||||
std::cout << "Sorted vector: ";
|
||||
for (size_t i = 0; i < vec.size(); ++i) {
|
||||
std::cout << vec[i] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}`
|
||||
|
||||
// Different format configurations
|
||||
formats := []struct {
|
||||
name string
|
||||
format string
|
||||
theme string
|
||||
}{
|
||||
{"svg_light", "svg", "github"},
|
||||
{"svg_dark", "svg", "github-dark"},
|
||||
{"png_presentation", "png", "dracula"},
|
||||
{"png_print", "png", "github"},
|
||||
}
|
||||
|
||||
freeze := freezelib.New().
|
||||
WithFont("Cascadia Code", 14).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(15, 0, 8).
|
||||
WithPadding(25)
|
||||
|
||||
for _, format := range formats {
|
||||
fmt.Printf("🎨 Generating %s format...\n", format.name)
|
||||
|
||||
freeze.WithTheme(format.theme)
|
||||
|
||||
var data []byte
|
||||
var err error
|
||||
var filename string
|
||||
|
||||
if format.format == "svg" {
|
||||
data, err = freeze.GenerateFromCode(code, "cpp")
|
||||
filename = fmt.Sprintf("output/multiformat_%s.svg", format.name)
|
||||
} else {
|
||||
data, err = freeze.GeneratePNGFromCode(code, "cpp")
|
||||
filename = fmt.Sprintf("output/multiformat_%s.png", format.name)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
err = os.WriteFile(filename, data, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Show file size
|
||||
info, _ := os.Stat(filename)
|
||||
fmt.Printf("✅ Generated: %s (%d bytes)\n", filename, info.Size())
|
||||
}
|
||||
}
|
||||
|
||||
// Concurrent processing example
|
||||
func concurrentProcessingExample() {
|
||||
fmt.Println("\n⚡ Concurrent Processing")
|
||||
fmt.Println("-----------------------")
|
||||
|
||||
// Sample code snippets for concurrent processing
|
||||
codeSnippets := []struct {
|
||||
name string
|
||||
code string
|
||||
lang string
|
||||
}{
|
||||
{
|
||||
"snippet1",
|
||||
`def fibonacci(n):
|
||||
if n <= 1:
|
||||
return n
|
||||
return fibonacci(n-1) + fibonacci(n-2)
|
||||
|
||||
print([fibonacci(i) for i in range(10)])`,
|
||||
"python",
|
||||
},
|
||||
{
|
||||
"snippet2",
|
||||
`function quickSort(arr) {
|
||||
if (arr.length <= 1) return arr;
|
||||
|
||||
const pivot = arr[Math.floor(arr.length / 2)];
|
||||
const left = arr.filter(x => x < pivot);
|
||||
const middle = arr.filter(x => x === pivot);
|
||||
const right = arr.filter(x => x > pivot);
|
||||
|
||||
return [...quickSort(left), ...middle, ...quickSort(right)];
|
||||
}`,
|
||||
"javascript",
|
||||
},
|
||||
{
|
||||
"snippet3",
|
||||
`public class BinarySearch {
|
||||
public static int search(int[] arr, int target) {
|
||||
int left = 0, right = arr.length - 1;
|
||||
|
||||
while (left <= right) {
|
||||
int mid = left + (right - left) / 2;
|
||||
|
||||
if (arr[mid] == target) return mid;
|
||||
if (arr[mid] < target) left = mid + 1;
|
||||
else right = mid - 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}`,
|
||||
"java",
|
||||
},
|
||||
{
|
||||
"snippet4",
|
||||
`use std::collections::HashMap;
|
||||
|
||||
fn word_count(text: &str) -> HashMap<String, usize> {
|
||||
text.split_whitespace()
|
||||
.map(|word| word.to_lowercase())
|
||||
.fold(HashMap::new(), |mut acc, word| {
|
||||
*acc.entry(word).or_insert(0) += 1;
|
||||
acc
|
||||
})
|
||||
}`,
|
||||
"rust",
|
||||
},
|
||||
}
|
||||
|
||||
// Create freeze instance
|
||||
freeze := freezelib.New().
|
||||
WithTheme("nord").
|
||||
WithFont("JetBrains Mono", 13).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithShadow(10, 0, 5).
|
||||
WithPadding(20)
|
||||
|
||||
// Use goroutines for concurrent processing
|
||||
var wg sync.WaitGroup
|
||||
results := make(chan string, len(codeSnippets))
|
||||
|
||||
fmt.Printf("🚀 Processing %d snippets concurrently...\n", len(codeSnippets))
|
||||
|
||||
for _, snippet := range codeSnippets {
|
||||
wg.Add(1)
|
||||
go func(s struct {
|
||||
name string
|
||||
code string
|
||||
lang string
|
||||
}) {
|
||||
defer wg.Done()
|
||||
|
||||
svgData, err := freeze.GenerateFromCode(s.code, s.lang)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("❌ Error processing %s: %v", s.name, err)
|
||||
return
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("output/concurrent_%s.svg", s.name)
|
||||
err = os.WriteFile(filename, svgData, 0644)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("❌ Error saving %s: %v", filename, err)
|
||||
return
|
||||
}
|
||||
|
||||
results <- fmt.Sprintf("✅ Generated: %s", filename)
|
||||
}(snippet)
|
||||
}
|
||||
|
||||
// Wait for all goroutines to complete
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(results)
|
||||
}()
|
||||
|
||||
// Collect results
|
||||
for result := range results {
|
||||
fmt.Println(result)
|
||||
}
|
||||
}
|
||||
|
||||
// Directory processing example
|
||||
func directoryProcessingExample() {
|
||||
fmt.Println("\n📁 Directory Processing")
|
||||
fmt.Println("-----------------------")
|
||||
|
||||
// Process all files in sample_files directory
|
||||
err := filepath.Walk("sample_files", func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Skip directories
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Only process certain file types
|
||||
ext := filepath.Ext(path)
|
||||
if !isSupportedFile(ext) {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("📄 Processing directory file: %s\n", path)
|
||||
|
||||
// Create themed freeze instance based on file type
|
||||
theme := getThemeForFile(ext)
|
||||
freeze := freezelib.New().
|
||||
WithTheme(theme).
|
||||
WithFont("SF Mono", 13).
|
||||
WithWindow(true).
|
||||
WithLineNumbers(true).
|
||||
WithPadding(20)
|
||||
|
||||
svgData, err := freeze.GenerateFromFile(path)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error processing %s: %v\n", path, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create output filename
|
||||
baseName := strings.TrimSuffix(filepath.Base(path), ext)
|
||||
outputFile := fmt.Sprintf("output/directory_%s.svg", baseName)
|
||||
|
||||
err = os.WriteFile(outputFile, svgData, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error saving %s: %v\n", outputFile, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s (theme: %s)\n", outputFile, theme)
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error walking directory: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
func detectLanguage(ext string) string {
|
||||
switch ext {
|
||||
case ".go":
|
||||
return "go"
|
||||
case ".py":
|
||||
return "python"
|
||||
case ".js":
|
||||
return "javascript"
|
||||
case ".css":
|
||||
return "css"
|
||||
case ".json":
|
||||
return "json"
|
||||
default:
|
||||
return "text"
|
||||
}
|
||||
}
|
||||
|
||||
func isSupportedFile(ext string) bool {
|
||||
supported := []string{".go", ".py", ".js", ".css", ".json", ".md", ".txt"}
|
||||
for _, s := range supported {
|
||||
if ext == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getThemeForFile(ext string) string {
|
||||
switch ext {
|
||||
case ".go":
|
||||
return "github-dark"
|
||||
case ".py":
|
||||
return "monokai"
|
||||
case ".js":
|
||||
return "dracula"
|
||||
case ".css":
|
||||
return "github"
|
||||
case ".json":
|
||||
return "nord"
|
||||
default:
|
||||
return "github"
|
||||
}
|
||||
}
|
113
examples/README.md
Normal file
113
examples/README.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# FreezeLib Examples
|
||||
|
||||
**Language / 语言**: [English](README.md) | [中文](README_CN.md)
|
||||
|
||||
This directory contains comprehensive examples demonstrating various features of FreezeLib.
|
||||
|
||||
## 📁 Example Categories
|
||||
|
||||
### [01-basic/](01-basic/) - Basic Usage
|
||||
- Simple code screenshot generation
|
||||
- Basic configuration
|
||||
- Getting started examples
|
||||
|
||||
### [02-formats/](02-formats/) - Output Formats
|
||||
- SVG output examples
|
||||
- PNG output examples
|
||||
- Format comparison
|
||||
- Quality settings
|
||||
|
||||
### [03-themes/](03-themes/) - Theme Showcase
|
||||
- Popular themes demonstration
|
||||
- Theme comparison
|
||||
- Custom theme creation
|
||||
|
||||
### [04-languages/](04-languages/) - Programming Languages
|
||||
- Syntax highlighting for different languages
|
||||
- Language-specific optimizations
|
||||
- Multi-language projects
|
||||
|
||||
### [05-terminal/](05-terminal/) - Terminal Output
|
||||
- ANSI color support
|
||||
- Terminal styling
|
||||
- Command output screenshots
|
||||
|
||||
### [06-advanced/](06-advanced/) - Advanced Configuration
|
||||
- Complex styling options
|
||||
- Performance optimization
|
||||
- Custom fonts and layouts
|
||||
|
||||
### [07-batch/](07-batch/) - Batch Processing
|
||||
- Multiple file processing
|
||||
- Automated workflows
|
||||
- Bulk operations
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
To run all examples:
|
||||
|
||||
```bash
|
||||
cd examples
|
||||
go run run_all_examples.go
|
||||
```
|
||||
|
||||
To run specific category:
|
||||
|
||||
```bash
|
||||
cd examples/01-basic
|
||||
go run main.go
|
||||
```
|
||||
|
||||
## 📊 Output Formats
|
||||
|
||||
Each example category demonstrates:
|
||||
- **SVG**: Vector format, perfect for web and documentation
|
||||
- **PNG**: Raster format, ideal for presentations and social media
|
||||
- **Quality comparisons**: Different settings and their effects
|
||||
|
||||
## 🎨 Visual Features Demonstrated
|
||||
|
||||
- **Syntax Highlighting**: 100+ programming languages
|
||||
- **Themes**: Light, dark, and custom themes
|
||||
- **Window Decorations**: macOS-style window controls
|
||||
- **Line Numbers**: Optional line numbering
|
||||
- **Shadows and Borders**: Visual enhancement effects
|
||||
- **Custom Fonts**: Typography options
|
||||
- **ANSI Colors**: Terminal output rendering
|
||||
- **Responsive Sizing**: Adaptive dimensions
|
||||
|
||||
## 📝 Code Examples Include
|
||||
|
||||
- **Web Development**: HTML, CSS, JavaScript, TypeScript
|
||||
- **Backend**: Go, Python, Java, C#, Rust
|
||||
- **Mobile**: Swift, Kotlin, Dart
|
||||
- **DevOps**: Docker, YAML, Shell scripts
|
||||
- **Data**: SQL, JSON, CSV processing
|
||||
- **Documentation**: Markdown, configuration files
|
||||
|
||||
## 🔧 Configuration Examples
|
||||
|
||||
Each category includes examples of:
|
||||
- Basic configuration
|
||||
- Advanced customization
|
||||
- Performance optimization
|
||||
- Error handling
|
||||
- Best practices
|
||||
|
||||
## 📖 Learning Path
|
||||
|
||||
1. **Start with [01-basic/](01-basic/)** - Learn fundamental concepts
|
||||
2. **Explore [02-formats/](02-formats/)** - Understand output options
|
||||
3. **Try [03-themes/](03-themes/)** - Discover visual styles
|
||||
4. **Check [04-languages/](04-languages/)** - See language support
|
||||
5. **Advanced topics** - Dive into specialized use cases
|
||||
|
||||
## 🤝 Contributing Examples
|
||||
|
||||
To add new examples:
|
||||
|
||||
1. Choose appropriate category or create new one
|
||||
2. Follow the naming convention: `example_name.go`
|
||||
3. Include both code and generated output
|
||||
4. Add documentation in README.md
|
||||
5. Test with `go run main.go`
|
114
examples/README_CN.md
Normal file
114
examples/README_CN.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# FreezeLib 示例集合
|
||||
|
||||
**Language / 语言**: [English](README.md) | [中文](README_CN.md)
|
||||
|
||||
本目录包含了展示 FreezeLib 各种功能的综合示例。
|
||||
|
||||
## 📁 示例分类
|
||||
|
||||
### [01-basic/](01-basic/) - 基础用法
|
||||
- 简单代码截图生成
|
||||
- 基本配置
|
||||
- 入门示例
|
||||
|
||||
### [02-formats/](02-formats/) - 输出格式
|
||||
- SVG 输出示例
|
||||
- PNG 输出示例
|
||||
- 格式对比
|
||||
- 质量设置
|
||||
|
||||
### [03-themes/](03-themes/) - 主题展示
|
||||
- 流行主题演示
|
||||
- 主题对比
|
||||
- 自定义主题创建
|
||||
|
||||
### [04-languages/](04-languages/) - 编程语言
|
||||
- 不同语言的语法高亮
|
||||
- 语言特定优化
|
||||
- 多语言项目
|
||||
|
||||
### [05-terminal/](05-terminal/) - 终端输出
|
||||
- ANSI 颜色支持
|
||||
- 终端样式
|
||||
- 命令输出截图
|
||||
|
||||
### [06-advanced/](06-advanced/) - 高级配置
|
||||
- 复杂样式选项
|
||||
- 性能优化
|
||||
- 自定义字体和布局
|
||||
|
||||
### [07-batch/](07-batch/) - 批量处理
|
||||
- 多文件处理
|
||||
- 自动化工作流
|
||||
- 批量操作
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
运行所有示例:
|
||||
|
||||
```bash
|
||||
cd examples
|
||||
go run run_all_examples.go
|
||||
```
|
||||
|
||||
运行特定分类:
|
||||
|
||||
```bash
|
||||
cd examples/01-basic
|
||||
go run main.go
|
||||
```
|
||||
|
||||
## 📊 输出格式
|
||||
|
||||
每个示例分类都演示:
|
||||
- **SVG**: 矢量格式,完美适用于网页和文档
|
||||
- **PNG**: 栅格格式,适合演示和社交媒体
|
||||
- **质量对比**: 不同设置及其效果
|
||||
|
||||
## 🎨 展示的视觉功能
|
||||
|
||||
- **语法高亮**: 100+ 种编程语言
|
||||
- **主题**: 浅色、深色和自定义主题
|
||||
- **窗口装饰**: macOS 风格窗口控件
|
||||
- **行号**: 可选行号显示
|
||||
- **阴影和边框**: 视觉增强效果
|
||||
- **自定义字体**: 排版选项
|
||||
- **ANSI 颜色**: 终端输出渲染
|
||||
- **响应式尺寸**: 自适应尺寸
|
||||
|
||||
## 📝 代码示例包括
|
||||
|
||||
- **Web 开发**: HTML, CSS, JavaScript, TypeScript
|
||||
- **后端**: Go, Python, Java, C#, Rust
|
||||
- **移动端**: Swift, Kotlin, Dart
|
||||
- **DevOps**: Docker, YAML, Shell 脚本
|
||||
- **数据**: SQL, JSON, CSV 处理
|
||||
- **文档**: Markdown, 配置文件
|
||||
|
||||
## 🔧 配置示例
|
||||
|
||||
每个分类都包含以下示例:
|
||||
- 基本配置
|
||||
- 高级自定义
|
||||
- 性能优化
|
||||
- 错误处理
|
||||
- 最佳实践
|
||||
|
||||
## 📖 学习路径
|
||||
|
||||
1. **从 [01-basic/](01-basic/) 开始** - 学习基本概念
|
||||
2. **探索 [02-formats/](02-formats/)** - 了解输出选项
|
||||
3. **尝试 [03-themes/](03-themes/)** - 发现视觉样式
|
||||
4. **查看 [04-languages/](04-languages/)** - 了解语言支持
|
||||
5. **高级主题** - 深入专业用例
|
||||
|
||||
## 🤝 贡献示例
|
||||
|
||||
添加新示例:
|
||||
|
||||
1. 选择合适的分类或创建新分类
|
||||
2. 遵循命名约定:`example_name.go`
|
||||
3. 包含代码和生成的输出
|
||||
4. 在 README.md 中添加文档
|
||||
5. 使用 `go run main.go` 测试
|
||||
|
Reference in New Issue
Block a user