slide-generator 1.0.0
Convert presentation outlines to PowerPoint files without requiring LLM
Requires Python: >=3.8
Keywords: powerpoint presentation slides html conversion

# Slide Generator

A powerful Python package to convert presentation outlines to professional PowerPoint files. No LLM required - just structured data in, PowerPoint out.

## Features

- **8 Professional Slide Layouts**
  - Title slide with gradient background
  - Content slides with rich text
  - Two-column comparison slides
  - Image slides (SVG or URL)
  - Image + text combination slides
  - Bullet point slides with nesting
  - Quote/inspirational slides
  - Chart/graph slides with Chart.js integration

- **In-Memory Processing**
  - No intermediate files saved to disk
  - HTML rendered to images using Playwright
  - Images compressed on-the-fly
  - Only final PowerPoint file written to disk

- **High-Quality Output**
  - 2x device scale factor for crisp rendering
  - Automatic image compression (JPEG quality 85)
  - 16:9 widescreen format
  - Professional typography and colors
  - Company logo and slide numbers

- **Chart Support**
  - Chart.js integration for interactive charts
  - Bar, line, and pie charts
  - Responsive design
  - Custom data from your outline

## Installation

### From Source
```bash
cd slide-generator
pip install -e .
```

### From PyPI (when published)
```bash
pip install slide-generator
```

### System Requirements
- Python 3.8+
- Chromium/Chrome browser (auto-installed by Playwright)

## Quick Start

### Basic Usage

```python
import asyncio
from slide_generator import PowerPointGenerator, SlideHTMLGenerator

async def create_presentation():
    # Define your slides (outline structure)
    outline = {
        "presentation": {
            "title": "My Presentation",
            "subtitle": "A Great Topic",
            "author": "John Doe",
            "slides": [
                {
                    "slide_number": 1,
                    "layout": "title",
                    "title": "Opening",
                    "subtitle": "Welcome",
                    "content": {
                        "title": "My Presentation",
                        "subtitle": "A Great Topic",
                        "author": "John Doe"
                    }
                },
                {
                    "slide_number": 2,
                    "layout": "content",
                    "title": "Main Content",
                    "subtitle": "Key Points",
                    "content": {
                        "body": "First paragraph of content.\n\nSecond paragraph with more details."
                    }
                },
                {
                    "slide_number": 3,
                    "layout": "bullets",
                    "title": "Key Benefits",
                    "subtitle": "Why This Matters",
                    "content": {
                        "points": [
                            "First benefit",
                            "Second benefit",
                            "Third benefit"
                        ]
                    }
                },
                {
                    "slide_number": 4,
                    "layout": "chart",
                    "title": "Performance Metrics",
                    "subtitle": "Data and Trends",
                    "content": {
                        "chart_type": "bar",
                        "chart_description": "Quarterly results",
                        "chart_json": '{"type":"bar","data":{"labels":["Q1","Q2","Q3","Q4"],"datasets":[{"label":"Revenue","data":[65,75,85,95],"backgroundColor":"#2563eb"}]},"options":{"responsive":true}}',
                        "text_heading": "Key Insights",
                        "text_body": "Strong growth trend",
                        "insights": ["Q4 achieved highest revenue", "Consistent growth"]
                    }
                }
            ]
        }
    }

    # Generate HTML slides
    html_slides = []
    for slide in outline["presentation"]["slides"]:
        slide_html = SlideHTMLGenerator.generate_slide_html(slide)
        from slide_generator import wrap_slide_html
        complete_html = wrap_slide_html(slide_html)
        html_slides.append(complete_html)

    # Create PowerPoint
    generator = PowerPointGenerator()
    await generator.create_powerpoint(
        html_slides=html_slides,
        output_path="my_presentation.pptx",
        compress_images=True,
        metadata={
            "title": outline["presentation"]["title"],
            "author": outline["presentation"]["author"],
            "subject": "A Great Presentation"
        }
    )

asyncio.run(create_presentation())
```

## Outline Structure

Your outline must follow this structure:

```json
{
  "presentation": {
    "title": "Presentation Title",
    "subtitle": "Presentation Subtitle",
    "author": "Author Name",
    "slides": [
      {
        "slide_number": 1,
        "layout": "title|content|two_column|image|image_text|bullets|quote|chart",
        "title": "Slide Title",
        "subtitle": "Slide Subtitle (optional)",
        "content": {}
      }
    ]
  }
}
```

## Slide Layouts

### 1. Title Slide
Opening slide with gradient background.
```json
{
  "layout": "title",
  "content": {
    "title": "Main Title",
    "subtitle": "Main Subtitle",
    "author": "Author Name"
  }
}
```

### 2. Content Slide
Standard informational slide with rich text.
```json
{
  "layout": "content",
  "content": {
    "body": "First paragraph.\n\nSecond paragraph."
  }
}
```

### 3. Two Column Slide
Side-by-side comparison layout.
```json
{
  "layout": "two_column",
  "content": {
    "left_column": {
      "heading": "Option A",
      "content": "Details about Option A"
    },
    "right_column": {
      "heading": "Option B",
      "content": "Details about Option B"
    }
  }
}
```

### 4. Image Slide
Full-slide image or SVG.
```json
{
  "layout": "image",
  "content": {
    "image_url": "https://example.com/image.png"
  }
}
```
Or with SVG:
```json
{
  "layout": "image",
  "content": {
    "image_svg": "<svg>...</svg>"
  }
}
```

### 5. Image + Text Slide
Image on left, text on right.
```json
{
  "layout": "image_text",
  "content": {
    "image_url": "https://example.com/image.png",
    "text_heading": "Key Information",
    "text_body": "Explanation of the image"
  }
}
```

### 6. Bullet Points Slide
Key points with optional nested bullets.
```json
{
  "layout": "bullets",
  "content": {
    "points": [
      "First bullet point",
      "Second bullet point",
      "Third bullet point"
    ]
  }
}
```

### 7. Quote Slide
Inspirational or key quote.
```json
{
  "layout": "quote",
  "content": {
    "quote_text": "A memorable quote that reinforces your message.",
    "author": "Source or Speaker"
  }
}
```

### 8. Chart Slide
Data visualization with Chart.js.
```json
{
  "layout": "chart",
  "content": {
    "chart_type": "bar|line|pie",
    "chart_description": "What the chart shows",
    "chart_json": "{\"type\":\"bar\",\"data\":{...},\"options\":{...}}",
    "text_heading": "Key Insights",
    "text_body": "Analysis of the data",
    "insights": [
      "Key insight 1",
      "Key insight 2"
    ]
  }
}
```

## Chart.js Configuration

For chart slides, provide a JSON string following Chart.js format:

```json
{
  "type": "bar",
  "data": {
    "labels": ["Q1", "Q2", "Q3", "Q4"],
    "datasets": [
      {
        "label": "Revenue",
        "data": [65, 75, 85, 95],
        "backgroundColor": "#2563eb"
      }
    ]
  },
  "options": {
    "responsive": true,
    "maintainAspectRatio": true
  }
}
```

## API Reference

### PowerPointGenerator

```python
generator = PowerPointGenerator(
    pixel_width=1280,      # Slide width in pixels
    pixel_height=720,      # Slide height in pixels
    scale=2.0              # Device scale factor for quality
)

# Convert HTML to image bytes (in memory)
image_bytes = await generator.html_to_image_bytes(html_content)

# Create PowerPoint from HTML slides
path = await generator.create_powerpoint(
    html_slides=list_of_html_strings,
    output_path="presentation.pptx",
    compress_images=True,
    metadata={
        "title": "My Presentation",
        "author": "John Doe",
        "subject": "A Great Topic"
    }
)
```

### SlideHTMLGenerator

```python
# Generate HTML for a single slide
html = SlideHTMLGenerator.generate_slide_html(slide_dict)

# Generate specific layout
html = SlideHTMLGenerator.generate_title_slide(slide_dict, slide_number)
html = SlideHTMLGenerator.generate_content_slide(slide_dict, slide_number)
# ... other layout methods

# Wrap slide in complete HTML document
complete_html = wrap_slide_html(slide_html)

# Escape HTML special characters
safe_text = SlideHTMLGenerator.escape_html(user_input)
```

## Performance

- **Memory Usage**: Single slide ~2-3 MB, 6-slide presentation ~15-20 MB peak
- **Processing Time**: HTML→Image ~2-3 sec per slide, PowerPoint creation < 1 sec
- **File Size**: 4 slides ~0.5 MB, 6 slides ~0.7 MB (with compression)

## Styling & Customization

All styling is embedded in the HTML templates. To customize:

1. **Colors**: Modify CSS variables in `html_generator.py`:
   ```css
   :root {
       --primary: #2563eb;      /* Main color */
       --secondary: #64748b;    /* Secondary color */
       --accent: #f59e0b;       /* Accent color */
   }
   ```

2. **Fonts**: Change font-family in `get_base_styles()`

3. **Logo**: Update `COMPANY_LOGO` URL in `SlideHTMLGenerator`

4. **Layout Dimensions**: Modify `pixel_width`, `pixel_height` in PowerPointGenerator

## Troubleshooting

### Playwright Browser Not Found
```bash
playwright install chromium
```

### Chart Not Rendering
- Ensure Chart.js CDN is accessible
- Check chart_json is valid JSON
- Verify chart is included in HTML (check wait_for_timeout)

### PowerPoint Won't Open
- Ensure all HTML is properly escaped
- Check file path is writable
- Verify PIL can process generated images

### Memory Issues
- Reduce number of slides
- Enable image compression
- Close other applications

## License

MIT License - See LICENSE file for details

## Contributing

Contributions are welcome! Please:
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Write tests
5. Submit a pull request

## Support

For issues, questions, or suggestions, please open an issue on GitHub.