45 lines
1.5 KiB
Python
45 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import date, datetime
|
|
from html import escape
|
|
from typing import Any
|
|
|
|
|
|
def text(value: Any) -> str:
|
|
if value is None or value == "":
|
|
return "nicht erfasst"
|
|
if isinstance(value, (date, datetime)):
|
|
return value.strftime("%d.%m.%Y")
|
|
return escape(str(value))
|
|
|
|
|
|
def paragraph(value: Any) -> str:
|
|
content = text(value)
|
|
return content.replace("\n", "<br>")
|
|
|
|
|
|
def yes_no(value: Any) -> str:
|
|
labels = {"yes": "Ja", "no": "Nein", "na": "Nicht zutreffend", True: "Ja", False: "Nein"}
|
|
return text(labels.get(value, value))
|
|
|
|
|
|
def definition_list(rows: list[tuple[str, Any]]) -> str:
|
|
items = "".join(
|
|
f"<div class=\"definition-row\"><dt>{text(label)}</dt><dd>{paragraph(value)}</dd></div>"
|
|
for label, value in rows
|
|
if value not in (None, "", [])
|
|
)
|
|
return f"<dl class=\"definition-list\">{items}</dl>"
|
|
|
|
|
|
def table(headers: list[str], rows: list[list[Any]], css_class: str = "") -> str:
|
|
head = "".join(f"<th>{text(header)}</th>" for header in headers)
|
|
body = "".join(
|
|
"<tr>" + "".join(f"<td>{paragraph(cell)}</td>" for cell in row) + "</tr>"
|
|
for row in rows
|
|
)
|
|
return f"<table class=\"data-table {css_class}\"><thead><tr>{head}</tr></thead><tbody>{body}</tbody></table>"
|
|
|
|
|
|
def section(chapter_id: str, title: str, body: str) -> str:
|
|
return f"<section class=\"chapter\" id=\"{text(chapter_id)}\"><h2>{text(title)}</h2>{body}</section>"
|