# How to Customize OpenMed Output to HTML Format: A Complete Guide

> Customize OpenMed output to HTML format effectively. Learn to use format predictions or subclass OutputFormatter for custom colors, templates, and filtering.

- Repository: [Maziyar Panahi/openmed](https://github.com/maziyarpanahi/openmed)
- Tags: how-to-guide
- Published: 2026-06-12

---

**You can customize OpenMed's HTML output by using the `format_predictions` function with `output_format="html"` or by subclassing `OutputFormatter` in [`openmed/processing/outputs.py`](https://github.com/maziyarpanahi/openmed/blob/main/openmed/processing/outputs.py) to override colors, templates, and filtering logic.**

OpenMed (maziyarpanahi/openmed) provides flexible formatting capabilities for model predictions through its `openmed.processing.outputs` module. When building medical NLP applications that require visual entity highlighting, you can generate rich HTML output complete with colored entity spans, confidence tooltips, and customizable CSS styling. This guide covers the architecture and practical techniques for tailoring HTML output to your specific UI requirements.

## Understanding the HTML Output Architecture

The HTML generation system centers on three core components defined in [`openmed/processing/outputs.py`](https://github.com/maziyarpanahi/openmed/blob/main/openmed/processing/outputs.py): the data structures holding predictions, the formatter class that transforms them, and the rendering methods that generate the final markup.

### Core Data Structures

**`PredictionResult`** aggregates all entities from a single inference pass. It contains the original text, model name, timestamp, processing time, and a list of **EntityPrediction** objects. Each `EntityPrediction` represents a single detected entity with its label, confidence score, and character offsets.

### The OutputFormatter Class

The **`OutputFormatter`** class manages the conversion from raw model outputs to formatted strings. It accepts formatting flags such as `include_confidence`, `confidence_threshold`, and `group_entities` during initialization. The `format_predictions` method constructs a `PredictionResult` from raw predictions, while `to_html` renders that result as an HTML string.

The HTML structure includes a wrapper `<div class="openmed-result">`, metadata headers displaying model name and timestamp, the original text with embedded `<span>` tags for each entity (carrying color-coded backgrounds and title attributes for tooltips), and a summary list of all detected entities.

## Basic HTML Generation

For standard HTML output without customization, use the module-level `format_predictions` function. This instantiates `OutputFormatter` internally and returns the rendered HTML.

```python
from openmed.processing.outputs import format_predictions

# Raw predictions from your medical NER model

raw_predictions = [
    {"entity": "B-PER", "word": "John", "score": 0.98, "start": 0, "end": 4},
    {"entity": "B-ORG", "word": "Acme Corp", "score": 0.95, "start": 10, "end": 19},
]

text = "John works at Acme Corp."

html = format_predictions(
    predictions=raw_predictions,
    original_text=text,
    model_name="medical-ner-model",
    output_format="html",
    include_confidence=True,
    confidence_threshold=0.5,
)

print(html)  # Returns HTML string ready for web rendering

```

The function processes predictions in [`openmed/processing/outputs.py`](https://github.com/maziyarpanahi/openmed/blob/main/openmed/processing/outputs.py) by sorting entities by start offset and iteratively inserting HTML tags while tracking offset shifts caused by the inserted markup.

## Customizing OpenMed HTML Output

Customization requires subclassing `OutputFormatter` and overriding specific methods. The two primary extension points are entity color mapping and HTML template generation.

### Modifying Entity Colors

Override **`_get_entity_color`** to implement custom color schemes for different entity types. The base method maps lowercase labels to CSS colors (e.g., `"person"` → `#FFE4E1`), but you can redefine this logic to match your application's design system.

```python
from openmed.processing.outputs import OutputFormatter

class CustomHtmlFormatter(OutputFormatter):
    def _get_entity_color(self, label: str) -> str:
        """Return pink for conditions, default colors for others."""
        if label.lower() == "condition":
            return "#FFC0CB"
        return super()._get_entity_color(label)

# Usage

formatter = CustomHtmlFormatter(include_confidence=True)
result = formatter.format_predictions(raw_predictions, text, "my-model")
html = formatter.to_html(result)

```

### Custom HTML Templates

To inject additional CSS or modify the HTML structure, override **`to_html`**. The method assembles HTML as plain strings, making it straightforward to prepend stylesheets or alter the wrapper markup.

```python
class StyledHtmlFormatter(OutputFormatter):
    def to_html(self, result):
        # Generate base HTML

        base_html = super().to_html(result)
        
        # Insert custom CSS after opening div

        custom_style = """
        <style>
            .entity { font-weight: bold; border-radius: 3px; }
            .entity-person { background-color: #e3f2fd; }
            .entity-organization { background-color: #f3e5f5; }
        </style>
        """
        return base_html.replace(
            '<div class="openmed-result">', 
            f'<div class="openmed-result">{custom_style}', 
            1
        )

```

### Filtering by Confidence Threshold

Control which entities appear in the HTML using the `confidence_threshold` parameter. Entities below the threshold are excluded from the `PredictionResult` before HTML generation.

```python
html = format_predictions(
    predictions=raw_predictions,
    original_text=text,
    model_name="medical-ner-model",
    output_format="html",
    confidence_threshold=0.9,  # Only entities ≥90% confidence

)

```

## Advanced Customization Examples

For production deployments requiring specific styling or preprocessing, combine subclassing with preprocessing hooks.

### Adding Custom CSS Classes

```python
class ClinicalFormatter(OutputFormatter):
    def _get_entity_color(self, label: str) -> str:
        # Standard medical color coding

        color_map = {
            "medication": "#ffebee",
            "condition": "#fff3e0",
            "procedure": "#e8f5e9",
            "symptom": "#e3f2fd"
        }
        return color_map.get(label.lower(), "#f5f5f5")
    
    def to_html(self, result):
        base = super().to_html(result)
        # Add clinical disclaimer footer

        disclaimer = "<footer class='disclaimer'>Reviewed by clinical staff</footer>"
        return base.replace("</div>", f"{disclaimer}</div>", 1)

```

## Summary

- **Primary entry point**: Use `format_predictions` in [`openmed/processing/outputs.py`](https://github.com/maziyarpanahi/openmed/blob/main/openmed/processing/outputs.py) with `output_format="html"` for standard HTML generation.
- **Architecture**: The `OutputFormatter` class handles the conversion from `PredictionResult` to HTML via the `to_html` method.
- **Color customization**: Override `_get_entity_color` in subclasses to implement entity-specific color schemes.
- **Template customization**: Override `to_html` to inject CSS, modify wrapper elements, or add disclaimers.
- **Confidence filtering**: Pass `confidence_threshold` to filter low-confidence entities before rendering.
- **Source files**: Core logic resides in [`openmed/processing/outputs.py`](https://github.com/maziyarpanahi/openmed/blob/main/openmed/processing/outputs.py), with CLI examples in [`openmed/cli/main.py`](https://github.com/maziyarpanahi/openmed/blob/main/openmed/cli/main.py).

## Frequently Asked Questions

### How do I change entity colors in OpenMed HTML output?

Subclass `OutputFormatter` and override the `_get_entity_color` method in [`openmed/processing/outputs.py`](https://github.com/maziyarpanahi/openmed/blob/main/openmed/processing/outputs.py). This method receives the entity label as a string and returns a CSS color value. Return custom hex codes for specific labels and call `super()._get_entity_color(label)` for default behavior on others.

### Can I add custom CSS styles to OpenMed HTML output?

Yes. Create a subclass of `OutputFormatter` and override the `to_html` method. Call `super().to_html(result)` to get the base HTML string, then use string manipulation (such as `replace`) to inject a `<style>` block or additional CSS classes before returning the final HTML.

### How do I filter low-confidence predictions from HTML output?

Pass the `confidence_threshold` parameter to `format_predictions` or initialize `OutputFormatter` with this value. Entities with confidence scores below the threshold are excluded from the `PredictionResult` before HTML generation, ensuring only high-confidence predictions appear in the rendered output.

### What is the difference between `format_predictions` and `OutputFormatter`?

`format_predictions` is a convenience function that instantiates `OutputFormatter` internally, calls `format_predictions` (the method), and returns the formatted output. `OutputFormatter` is the class containing the actual formatting logic, HTML generation (`to_html`), and customization hooks like `_get_entity_color`. Use the function for simple cases and the class directly when subclassing for customization.