WFGY/ProblemMap/Atlas/Fixes/official/demos/shared/display_helpers.py
2026-03-13 08:55:54 +08:00

200 lines
5 KiB
Python

from __future__ import annotations
import json
from typing import Any, Mapping, Sequence
def _try_import_ipython_display():
try:
from IPython.display import Markdown, display # type: ignore
return display, Markdown
except Exception:
return None, None
def _to_pretty_json(data: Any, indent: int = 2) -> str:
return json.dumps(data, indent=indent, ensure_ascii=False, sort_keys=False)
def _escape_markdown_text(value: str) -> str:
return value.replace("_", "\\_")
def print_divider(char: str = "=", width: int = 88) -> None:
print(char * width)
def print_title(title: str, width: int = 88) -> None:
print()
print_divider("=", width)
print(title)
print_divider("=", width)
def print_subtitle(title: str, width: int = 88) -> None:
print()
print_divider("-", width)
print(title)
print_divider("-", width)
def print_json_block(title: str, data: Any, width: int = 88) -> None:
print_subtitle(title, width)
print(_to_pretty_json(data))
def print_text_block(title: str, text: str, width: int = 88) -> None:
print_subtitle(title, width)
print(text)
def print_key_values(title: str, data: Mapping[str, Any], width: int = 88) -> None:
print_subtitle(title, width)
max_key_len = max((len(str(key)) for key in data.keys()), default=0)
for key, value in data.items():
print(f"{str(key).ljust(max_key_len)} : {value}")
def print_before_after(
before: Any,
after: Any,
before_label: str = "Before",
after_label: str = "After",
width: int = 88,
) -> None:
print_subtitle(before_label, width)
if isinstance(before, (dict, list)):
print(_to_pretty_json(before))
else:
print(before)
print_subtitle(after_label, width)
if isinstance(after, (dict, list)):
print(_to_pretty_json(after))
else:
print(after)
def print_bullets(title: str, items: Sequence[str], width: int = 88) -> None:
print_subtitle(title, width)
for item in items:
print(f"- {item}")
def display_markdown_block(markdown_text: str) -> None:
display, Markdown = _try_import_ipython_display()
if display is not None and Markdown is not None:
display(Markdown(markdown_text))
else:
print(markdown_text)
def display_section_title(title: str, level: int = 2) -> None:
safe_level = min(max(level, 1), 6)
display_markdown_block(f"{'#' * safe_level} {title}")
def display_callout(text: str) -> None:
display_markdown_block(f"> {text}")
def display_json_card(title: str, data: Any) -> None:
json_text = _to_pretty_json(data)
markdown = f"### {title}\n\n```json\n{json_text}\n```"
display_markdown_block(markdown)
def display_route_card(
primary_family: str,
secondary_family: str,
best_current_fit: str,
broken_invariant: str,
title: str = "Route Summary",
) -> None:
markdown = "\n".join(
[
f"### {title}",
"",
f"- **Primary family:** {primary_family}",
f"- **Secondary family:** {secondary_family}",
f"- **Best current fit:** {best_current_fit}",
f"- **Broken invariant:** {broken_invariant}",
]
)
display_markdown_block(markdown)
def display_mode_note(mode_label: str, note: str | None = None) -> None:
safe_label = _escape_markdown_text(mode_label)
markdown_lines = [
"### Mode",
"",
f"- **Current mode:** {safe_label}",
]
if note:
markdown_lines.append(f"- **Note:** {note}")
display_markdown_block("\n".join(markdown_lines))
def display_before_after_card(
before: Any,
after: Any,
before_label: str = "Before",
after_label: str = "After",
title: str = "Before / After",
) -> None:
if isinstance(before, (dict, list)):
before_text = _to_pretty_json(before)
else:
before_text = str(before)
if isinstance(after, (dict, list)):
after_text = _to_pretty_json(after)
else:
after_text = str(after)
markdown = "\n".join(
[
f"### {title}",
"",
f"#### {before_label}",
"",
"```text",
before_text,
"```",
"",
f"#### {after_label}",
"",
"```text",
after_text,
"```",
]
)
display_markdown_block(markdown)
def display_checklist(title: str, items: Sequence[str]) -> None:
markdown = [f"### {title}", ""]
for item in items:
markdown.append(f"- [x] {item}")
display_markdown_block("\n".join(markdown))
__all__ = [
"print_divider",
"print_title",
"print_subtitle",
"print_json_block",
"print_text_block",
"print_key_values",
"print_before_after",
"print_bullets",
"display_markdown_block",
"display_section_title",
"display_callout",
"display_json_card",
"display_route_card",
"display_mode_note",
"display_before_after_card",
"display_checklist",
]