Skip to content

Commit 984192d

Browse files
committed
TextFrame(feat[overflow_behavior]): Add truncate mode for content overflow
why: Allow flexible handling of oversized content - either error with visual diagnostic or silently truncate to fit. what: - Add OverflowBehavior type alias for "error" | "truncate" - Add overflow_behavior parameter with default "error" (backward compatible) - Implement truncate logic to clip width and height - Update docstrings to reflect new behavior
1 parent c183a48 commit 984192d

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

tests/textframe/core.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
if t.TYPE_CHECKING:
1313
from collections.abc import Sequence
1414

15+
OverflowBehavior = t.Literal["error", "truncate"]
16+
1517

1618
class ContentOverflowError(ValueError):
1719
"""Raised when content does not fit into the configured frame dimensions.
@@ -38,6 +40,10 @@ class TextFrame:
3840
Width of the inner content area.
3941
content_height : int
4042
Height of the inner content area.
43+
overflow_behavior : OverflowBehavior
44+
How to handle content that exceeds frame dimensions.
45+
- "error": Raise ContentOverflowError with visual diagnostic.
46+
- "truncate": Silently clip content to fit.
4147
fill_char : str
4248
Character to pad empty space. Defaults to space.
4349
content : list[str]
@@ -56,6 +62,7 @@ class TextFrame:
5662

5763
content_width: int
5864
content_height: int
65+
overflow_behavior: OverflowBehavior = "error"
5966
fill_char: str = " "
6067
content: list[str] = field(default_factory=list)
6168

@@ -78,7 +85,7 @@ def __post_init__(self) -> None:
7885
raise ValueError(msg)
7986

8087
def set_content(self, lines: Sequence[str]) -> None:
81-
"""Set content, applying validation logic.
88+
"""Set content, applying validation or truncation based on overflow_behavior.
8289
8390
Parameters
8491
----------
@@ -88,7 +95,7 @@ def set_content(self, lines: Sequence[str]) -> None:
8895
Raises
8996
------
9097
ContentOverflowError
91-
If content exceeds frame dimensions.
98+
If content exceeds frame dimensions and overflow_behavior is "error".
9299
"""
93100
input_lines = list(lines)
94101

@@ -99,12 +106,18 @@ def set_content(self, lines: Sequence[str]) -> None:
99106
is_overflow = max_w > self.content_width or max_h > self.content_height
100107

101108
if is_overflow:
102-
visual = self._render_overflow(input_lines, max_w, max_h)
103-
raise ContentOverflowError(
104-
f"Content ({max_w}x{max_h}) exceeds frame "
105-
f"({self.content_width}x{self.content_height})",
106-
overflow_visual=visual,
107-
)
109+
if self.overflow_behavior == "error":
110+
visual = self._render_overflow(input_lines, max_w, max_h)
111+
msg = (
112+
f"Content ({max_w}x{max_h}) exceeds frame "
113+
f"({self.content_width}x{self.content_height})"
114+
)
115+
raise ContentOverflowError(msg, overflow_visual=visual)
116+
# Truncate mode: clip to frame dimensions
117+
input_lines = [
118+
line[: self.content_width]
119+
for line in input_lines[: self.content_height]
120+
]
108121

109122
self.content = input_lines
110123

0 commit comments

Comments
 (0)