#markdown-html #html #seo #web-dev

html-generator

A robust Rust library designed for transforming Markdown into SEO-optimized, accessible HTML. Featuring front matter extraction, custom header processing, table of contents generation, and performance optimization for web projects of any scale.

3 releases

0.0.3 Dec 29, 2024
0.0.2 Dec 1, 2024
0.0.1 Oct 7, 2024

#507 in Web programming

Download history 94/week @ 2024-10-01 134/week @ 2024-10-08 26/week @ 2024-10-15 81/week @ 2024-10-22 45/week @ 2024-10-29 158/week @ 2024-11-05 52/week @ 2024-11-12 40/week @ 2024-11-19 126/week @ 2024-11-26 122/week @ 2024-12-03 110/week @ 2024-12-10 290/week @ 2024-12-17 350/week @ 2024-12-24 233/week @ 2024-12-31 163/week @ 2025-01-07

1,050 downloads per month
Used in 4 crates (2 directly)

MIT/Apache

360KB
7K SLoC

HTML Generator logo

HTML Generator (html-generator)

A high-performance Rust library that transforms Markdown into semantically rich, accessible HTML with WCAG 2.1 compliance.

Made With Love Crates.io lib.rs Docs.rs Codecov Build Status GitHub

WebsiteDocumentationReport BugRequest FeatureContributing Guidelines

Overview

HTML Generator is a high-performance Rust library for transforming Markdown into semantically rich, accessible HTML.

Key Features

Markdown Conversion

  • Core Processing:
    • Standard Markdown to HTML transformation
    • Configurable parsing with ComrakOptions
    • Front matter extraction support
    • Basic syntax highlighting via syntect
    • Inline HTML preservation

Accessibility and Semantic Markup

  • ARIA and Accessibility Features:
    • Automated ARIA attribute generation for:
      • Buttons
      • Form elements
      • Navigation structures
      • Interactive components
    • WCAG 2.1 validation checks
    • Semantic HTML structure preservation
    • Automatic role inference for HTML elements

Performance Optimizations

  • Efficient Processing:
    • O(n) time complexity parsing
    • Constant memory overhead for small documents
    • Synchronous and asynchronous HTML generation methods
    • Minimal runtime overhead
    • Optional HTML minification

Advanced Configuration

  • Flexible Transformation:
    • Language-specific rendering
    • Configurable syntax highlighting
    • Custom block processing
    • Emoji handling (limited)
    • SEO metadata generation

Installation

Add to your Cargo.toml:

[dependencies]
html-generator = "0.0.3"

Basic Usage

use html_generator::{generate_html, HtmlConfig};
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let markdown = "# Welcome\n\nThis is **HTML Generator**!";
    let config = HtmlConfig::default();
    let html = generate_html(markdown, &config)?;
    println!("{}", html);
    Ok(())
}

Advanced Usage Configuration

use html_generator::HtmlConfig;
use html_generator::error::HtmlError;

fn main() -> Result<(), HtmlError> {
    let config = HtmlConfig::builder()
        .with_language("en-GB")
        .with_syntax_highlighting(true, Some("monokai".to_string()))
        .build()?;

    println!("Built config: {:?}", config);
    Ok(())
}

Processing Methods

Synchronous Processing

use html_generator::{generate_html, HtmlConfig};
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let markdown = "# Hello from synchronous processing";
    let config = HtmlConfig::default();
    let html = generate_html(markdown, &config)?;
    println!("{}", html);
    Ok(())
}

Asynchronous Processing

# use html_generator::performance::async_generate_html;
# use std::error::Error;
#
# // We hide the async main to avoid doc-test errors about `.await`.
# // The code inside demonstrates how you'd normally use `async_generate_html`.
# async fn async_main_example() -> Result<(), Box<dyn Error>> {
    let markdown = "# Async Processing\n\nThis is **HTML Generator**!";
    let html = async_generate_html(markdown).await?;
    println!("{}", html);
    Ok(())
# }

Error Handling

use html_generator::{generate_html, HtmlConfig};
use html_generator::error::HtmlError;

fn handle_conversion_error(markdown: &str) -> Result<(), HtmlError> {
    let config = HtmlConfig::default();
    match generate_html(markdown, &config) {
        Ok(html) => println!("Conversion successful: {}", html),
        Err(HtmlError::InvalidInput(msg)) => {
            eprintln!("Invalid input: {}", msg);
        },
        Err(HtmlError::InputTooLarge(size)) => {
            eprintln!("Input too large: {} bytes", size);
        },
        Err(e) => eprintln!("Unexpected error: {}", e),
    }
    Ok(())
}

Examples

HTML Generator provides many advanced capabilities for accessibility, ARIA attributes, and custom Markdown styling. Below is a summary of what you can explore. For more detailed code, see the src/examples/ directory in this repository.

ARIA Elements & Accessibility

Add ARIA attributes to common HTML elements (buttons, forms, tables, and more) to ensure accessibility compliance. The library automatically infers roles and labels for screen readers.

Example Snippet (from aria_elements_example.rs):

use html_generator::accessibility::add_aria_attributes;
use html_generator::error::HtmlError;

fn main() -> Result<(), HtmlError> {
    // Basic HTML snippet for a button
    let html_button = "<button>Click me</button>";

    // Enhance with ARIA attributes
    let enhanced_button =
        add_aria_attributes(html_button, None).map_err(|e| {
            // Convert from an accessibility::Error to an HtmlError
            HtmlError::InvalidInput(e.to_string())
        })?;
    println!("Original:  {}", html_button);
    println!("Enhanced:  {}", enhanced_button);

    Ok(())
}

Run the full ARIA demo:

cargo run --example aria

This will print out multiple examples showcasing enhancements for buttons, forms, navigation elements, tables, live regions, and nested components.

Custom Markdown Styling

Demonstrate transforming extended Markdown features such as:

  • Custom blocks (e.g., :::note, :::warning)
  • Inline .class="..." directives for images or elements
  • Syntax highlighting for fenced code blocks
  • Blockquotes with optional citation

…and much more.

Example Snippet (from style_example.rs):

use html_generator::error::HtmlError;
use html_generator::generator::markdown_to_html_with_extensions;

fn main() -> Result<(), HtmlError> {
    let markdown = r":::note
Custom note block with a specific style
:::";

    match markdown_to_html_with_extensions(markdown) {
        Ok(html) => println!("Converted:\n{}", html),
        Err(e) => println!("Error: {}", e),
    }
    Ok(())
}

Run the full style demo:

cargo run --example style

This will print out multiple styled examples (custom blocks, images, tables, bullet lists, code blocks, etc.) and show how they render as HTML.

Bringing It All Together

If you’d like to combine accessibility features and custom Markdown styling, you can configure your HtmlConfig to enable:

  1. Syntax highlighting
  2. ARIA attribute generation
  3. Custom block parsing
  4. Emoji support

…thereby providing a powerful, end-to-end Markdown-to-HTML transformation pipeline suitable for high-performance, semantically rich, and user-friendly content.

Performance Characteristics

Document Scale Processing Time Memory Utilization
Small (<1KB) ~0.1ms Constant O(1)
Medium (10KB) ~1ms Linear O(n)
Large (100KB) ~10ms Linear O(n)

Platform Support

Platform Status Rust Version Notes
Linux ✅ Fully 1.56+ Comprehensive support
macOS ✅ Fully 1.56+ Native performance
Windows ✅ Fully 1.56+ Complete compatibility
WebAssembly ⚠️ Partial 1.56+ Limited feature support

Continuous Integration

We use GitHub Actions for comprehensive testing:

  • Cross-platform compatibility checks
  • Extensive test coverage

View CI Workflow

Conversion Error Handling

# use html_generator::{generate_html, HtmlConfig};
# use html_generator::error::HtmlError;
#
fn handle_conversion_error(markdown: &str) -> Result<(), HtmlError> {
    // We'll define a config for this snippet:
    let config = HtmlConfig::default();
    match generate_html(markdown, &config) {
        Ok(html) => println!("Conversion successful"),
        Err(HtmlError::InvalidInput(msg)) => {
            eprintln!("Invalid input: {}", msg);
        },
        Err(HtmlError::InputTooLarge(size)) => {
            eprintln!("Input too large: {} bytes", size);
        },
        Err(HtmlError::Io(io_error)) => {
            eprintln!("I/O error occurred: {}", io_error);
        },
        // If your crate doesn't actually have a `Markdown` variant, remove this block
        // Err(HtmlError::Markdown(markdown_error)) => {
        //     eprintln!("Markdown processing error: {}", markdown_error);
        // },
        Err(e) => eprintln!("Unexpected error: {}", e),
    }
    Ok(())
}

Running Examples

# Basic example
cargo run --example basic

# Accessibility demo
cargo run --example aria

# Performance benchmark
cargo run --example performance

Contributing

We welcome contributions! See CONTRIBUTING.md for details on:

  • Reporting issues
  • Suggesting features
  • Submitting pull requests

Licensing

Dual-licensed: Apache 2.0 & MIT

Acknowledgements

Special thanks to the Rust community and open-source contributors.

Dependencies

~26–38MB
~610K SLoC