Coverage for lintro / formatters / styles / html.py: 100%
16 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""HTML output style implementation."""
3from typing import Any
5from lintro.formatters.core.format_registry import OutputStyle
8class HtmlStyle(OutputStyle):
9 """Output format that renders data as HTML table."""
11 def format(
12 self,
13 columns: list[str],
14 rows: list[list[Any]],
15 tool_name: str | None = None,
16 **kwargs: Any,
17 ) -> str:
18 """Format a table given columns and rows as HTML.
20 Args:
21 columns: List of column header names.
22 rows: List of row values (each row is a list of cell values).
23 tool_name: Optional tool name to include in context.
24 **kwargs: Extra options ignored by this formatter.
26 Returns:
27 Formatted data as HTML table string.
28 """
29 if not rows:
30 return "<p>No issues found.</p>"
32 # Build the header
33 header_cells = "".join(f"<th>{col}</th>" for col in columns)
34 header = f"<tr>{header_cells}</tr>"
36 # Build the rows
37 formatted_rows = []
38 for row in rows:
39 # Ensure row has same number of elements as columns
40 padded_row = row + [""] * (len(columns) - len(row))
41 # Escape HTML characters in cell values
42 escaped_cells = [
43 str(cell)
44 .replace("&", "&")
45 .replace("<", "<")
46 .replace(">", ">")
47 for cell in padded_row
48 ]
49 row_cells = "".join(f"<td>{cell}</td>" for cell in escaped_cells)
50 formatted_rows.append(f"<tr>{row_cells}</tr>")
52 # Combine all parts
53 table_content = header + "".join(formatted_rows)
54 return f"<table>{table_content}</table>"