waddling-errors 0.7.3

Structured, secure-by-default diagnostic codes for distributed systems with no_std and role-based documentation
Documentation
# HTML Documentation Customization

## Overview

As of v0.5.0, waddling-errors supports comprehensive HTML documentation customization, allowing projects to brand and style their error documentation.

## Features

### 1. **Asset Extraction**
- CSS and JavaScript are now in separate files: `src/doc_generator/html/assets/`
  - `default.css` (1,073 lines)
  - `default.js` (1,363 lines)
- Embedded at compile-time using `include_str!()`
- Easier to edit with full syntax highlighting support

### 2. **HtmlCustomization API**
Full builder-pattern API for customizing documentation:

```rust
use waddling_errors::doc_generator::{DocRegistry, HtmlCustomization, HtmlRenderer};

let custom = HtmlCustomization::new()
    .with_logo("https://example.com/logo.svg", "MyProject")
    .with_accent_color("#FF5722", "#FF8A65")
    .with_custom_css(".error-card { border-radius: 16px; }")
    .with_footer("<p>© 2025 MyProject</p>");

let renderer = HtmlRenderer::with_customization(custom);
```

### 3. **Customization Options**

| Method | Description |
|--------|-------------|
| `with_logo(url, alt)` | Add custom logo next to project name |
| `with_accent_color(light, dark)` | Theme colors via CSS variables |
| `with_custom_css(css)` | Append custom CSS to defaults |
| `replace_css(css)` | Completely replace default CSS |
| `with_custom_js(js)` | Append custom JavaScript |
| `replace_js(js)` | Completely replace default JavaScript |
| `with_header(html)` | Add custom HTML at top of page |
| `with_footer(html)` | Add custom HTML at bottom of page |

### 4. **Logo Support**
- External URL: `https://example.com/logo.png`
- Data URI: `data:image/svg+xml,%3Csvg...%3E`
- Automatic sizing: 40px height, maintains aspect ratio
- Positioned before the duck emoji in the h1

### 5. **Theme Support**
Accent colors applied via CSS variables:
```css
:root {
    --accent-color: #FF5722;
}
@media (prefers-color-scheme: dark) {
    :root {
        --accent-color: #FF8A65;
    }
}
```

## Usage Examples

### Basic Branding
```rust
let branding = HtmlCustomization::new()
    .with_logo("https://example.com/logo.svg", "MyProject")
    .with_accent_color("#2196F3", "#64B5F6");
```

### Custom Styling
```rust
let custom_css = r#"
    .error-card {
        border-radius: 16px;
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    }
    h1 { font-family: 'Georgia', serif; }
"#;

let styled = HtmlCustomization::new()
    .with_custom_css(custom_css.to_string());
```

### Complete Replacement (Advanced)
```rust
let minimal_css = r#"
    body { 
        background: #000; 
        color: #0f0;
        font-family: monospace;
    }
    .error-card { border: 2px solid #0f0; }
"#;

let replaced = HtmlCustomization::new()
    .replace_css(minimal_css.to_string());
```

### Custom Footer
```rust
let with_footer = HtmlCustomization::new()
    .with_footer("<p>© 2025 MyProject | <a href='mailto:support@example.com'>Support</a></p>");
```

## Testing

Run the example to see all customization options:

```bash
cargo run --example html_customization_demo --features="doc-gen,metadata,hash"
```

This generates 6 variants in `target/docs/`:
- `basic/` - No customization
- `branded/` - Logo + accent colors
- `styled/` - Custom CSS additions
- `footer/` - Custom footer HTML
- `replaced/` - Complete CSS replacement
- `data-uri/` - Data URI logo example

## Architecture

### File Structure
```
src/doc_generator/html/
├── assets/
│   ├── default.css      # External CSS file
│   └── default.js       # External JavaScript file
├── customization.rs     # HtmlCustomization struct
├── mod.rs               # include_str!() loading
└── template.rs          # HTML generation with customization
```

### Integration Flow
```
HtmlCustomization
  ↓
HtmlRenderer::with_customization()
  ↓
HtmlConfig { customization: Option<&HtmlCustomization> }
  ↓
generate_html() → generate_template()
  ↓
Helper functions:
  - _generate_css() - Merges default + custom CSS
  - _generate_js() - Merges default + custom JS
  - _generate_logo() - Generates logo HTML
  - _generate_header() - Generates custom header
  - _generate_footer() - Generates custom footer
```

## Breaking Changes (v0.5.0)

1. **HtmlRenderer** changed from unit struct to struct with field:
   ```rust
   // Old (v0.4.0)
   let renderer = HtmlRenderer;
   
   // New (v0.5.0)
   let renderer = HtmlRenderer::new();
   // or
   let renderer = HtmlRenderer::with_customization(custom);
   ```

2. **CSS/JS Files** removed from source:
   - Deleted: `src/doc_generator/html/css.rs`
   - Deleted: `src/doc_generator/html/javascript.rs`
   - Replaced with: `assets/default.css` and `assets/default.js`

## Benefits

### For Users
- ✅ Brand documentation with logos and colors
- ✅ Match project's design system
- ✅ Add custom analytics or tracking
- ✅ Include legal notices in footer
- ✅ Override any styling as needed

### For Developers
- ✅ CSS/JS files have full syntax highlighting
- ✅ Easier to edit and maintain styles
- ✅ No more 2,436 lines of embedded strings
- ✅ Clean separation of concerns
- ✅ Type-safe builder API

### For the Codebase
- ✅ Reduced code size (deleted css.rs and javascript.rs)
- ✅ Better organization with assets/ folder
- ✅ Compile-time embedding (no runtime file I/O)
- ✅ No impact on binary size or performance

## Future Enhancements

Potential additions for future versions:
- [ ] Multiple theme presets (dark, light, high-contrast)
- [ ] Logo positioning options (left, center, right)
- [ ] Custom fonts support
- [ ] Layout customization (grid vs. list)
- [ ] Custom search placeholder text
- [ ] Internationalization (i18n) support
- [ ] Template inheritance system

## Migration Guide

### From v0.4.0 to v0.5.0

**Before:**
```rust
let renderer = HtmlRenderer;
registry.render(vec![Box::new(renderer)], "target/docs")?;
```

**After:**
```rust
let renderer = HtmlRenderer::new();
registry.render(vec![Box::new(renderer)], "target/docs")?;
```

**With Customization:**
```rust
let custom = HtmlCustomization::new()
    .with_logo("logo.svg", "MyProject")
    .with_accent_color("#FF5722", "#FF8A65");

let renderer = HtmlRenderer::with_customization(custom);
registry.render(vec![Box::new(renderer)], "target/docs")?;
```

## Related Documentation

- [REFACTORING_ANALYSIS.md]REFACTORING_ANALYSIS.md - Full codebase analysis that led to this work
- [API Documentation]api-documentation.md - Complete API reference
- [examples/html_customization_demo.rs]../examples/html_customization_demo.rs - Working examples

## Credits

This feature was implemented as part of the HIGH PRIORITY recommendations from the comprehensive refactoring analysis (November 2025). The goal was to improve maintainability and provide users with branding capabilities.