This commit is contained in:
nose
2025-12-07 20:52:47 -08:00
parent e3747555bf
commit be37eb9d5b
6 changed files with 373 additions and 28 deletions

View File

@@ -8,7 +8,8 @@ from __future__ import annotations
from typing import Any, Dict, List, Optional, Sequence
from rich.console import Console
from rich import box
from rich.console import Console, Group
from rich.panel import Panel
from rich.table import Table
@@ -92,32 +93,63 @@ class Renderer:
# Internal renderers -------------------------------------------------
def _render_card(self, card: Card) -> None:
suit = getattr(card, "suit", None)
lines: List[str] = [f"Arcana: {card.arcana}"]
if suit is not None and getattr(suit, "name", None):
lines.append(f"Suit: {suit.name}")
if getattr(card, "pip", 0):
lines.append(f"Pip: {card.pip}")
if getattr(card, "court_rank", ""):
lines.append(f"Court Rank: {card.court_rank}")
"""Render a card in a rectangular layout with top/middle/bottom bars."""
name = getattr(card, "name", "")
arcana = getattr(card, "arcana", "")
suit_obj = getattr(card, "suit", None)
suit = getattr(suit_obj, "name", "") if suit_obj is not None else ""
pip = getattr(card, "pip", None)
number = getattr(card, "number", "")
keywords = getattr(card, "keywords", None) or []
meaning = getattr(card, "meaning", None)
if meaning is not None:
if getattr(meaning, "upright", None):
lines.append(f"Upright: {meaning.upright}")
if getattr(meaning, "reversed", None):
lines.append(f"Reversed: {meaning.reversed}")
keywords = getattr(card, "keywords", None)
top = Table.grid(expand=True)
for align in ("left", "center", "right"):
top.add_column(justify=align)
top_left = suit or arcana
top_center = name
top_right = f"#{number}" if number not in (None, "") else ""
top.add_row(top_left, top_center, top_right)
body_lines = [f"Arcana: {arcana or '-'}"]
if suit:
body_lines.append(f"Suit: {suit}")
if pip:
body_lines.append(f"Pip: {pip}")
if getattr(card, "court_rank", ""):
body_lines.append(f"Court Rank: {card.court_rank}")
if keywords:
lines.append(f"Keywords: {', '.join(keywords)}")
reversed_keywords = getattr(card, "reversed_keywords", None)
if reversed_keywords:
lines.append(f"Reversed Keywords: {', '.join(reversed_keywords)}")
body_lines.append(f"Keywords: {', '.join(keywords)}")
guidance = getattr(card, "guidance", None)
if guidance:
lines.append(f"Guidance: {guidance}")
self.console.print(
Panel("\n".join(lines), title=f"{card.number}: {card.name}", expand=False)
body_lines.append(f"Guidance: {guidance}")
body = Panel("\n".join(body_lines), box=box.MINIMAL, padding=(1, 1))
bottom = Table(
show_header=False,
expand=True,
box=box.SIMPLE_HEAVY,
show_edge=True,
pad_edge=False,
)
bottom.add_column(justify="left")
bottom.add_column(justify="center")
bottom.add_column(justify="right")
bottom.add_row(
self._label_block("Upright", getattr(meaning, "upright", None)),
self._label_block("Reversed", getattr(meaning, "reversed", None)),
self._label_block("Keywords", ", ".join(keywords) if keywords else None),
)
card_panel = Panel(
Group(top, body, bottom),
box=box.SQUARE,
padding=0,
title=name,
expand=False,
)
self.console.print(card_panel)
def _render_object(self, obj: Any) -> None:
attrs = {k: v for k, v in vars(obj).items() if not k.startswith("_")}
@@ -255,6 +287,11 @@ class Renderer:
def _humanize_key(key: str) -> str:
return key.replace("_", " ")
@staticmethod
def _label_block(label: str, value: Optional[str]) -> str:
safe_val = value if value not in (None, "") else ""
return f"{label}:\n{safe_val}"
class PlanetRenderer:
"""Type-specific table rendering for planets."""