mirror of https://github.com/Textualize/rich.git
tidier rich text
This commit is contained in:
parent
7481db402b
commit
d0ece455da
69
rich/text.py
69
rich/text.py
|
@ -13,9 +13,9 @@ class TextSpan(NamedTuple):
|
|||
|
||||
start: int
|
||||
end: int
|
||||
style: Optional[str]
|
||||
style: str
|
||||
|
||||
def adjust_offset(self, offset: int) -> TextSpan:
|
||||
def adjust_offset(self, offset: int, max_length) -> TextSpan:
|
||||
"""Get a new `TextSpan` with start and end adjusted.
|
||||
|
||||
Args:
|
||||
|
@ -24,7 +24,11 @@ class TextSpan(NamedTuple):
|
|||
Returns:
|
||||
TextSpan: A new text span.
|
||||
"""
|
||||
return TextSpan(self.start + offset, self.end + offset, self.style)
|
||||
return TextSpan(
|
||||
min(max_length, max(0, self.start + offset)),
|
||||
min(max_length, max(0, self.end + offset)),
|
||||
self.style,
|
||||
)
|
||||
|
||||
def slice_text(self, text: str) -> str:
|
||||
"""Slice the text according to the start and end offsets.
|
||||
|
@ -59,32 +63,59 @@ class RichText:
|
|||
return f"RichText({self.text!r})"
|
||||
|
||||
def stylize(self, start: int, end: int, style: str) -> None:
|
||||
self._spans.append(TextSpan(start, end, style))
|
||||
"""Apply a style to a portion of the text.
|
||||
|
||||
Args:
|
||||
start (int): Start offset.
|
||||
end (int): End offset.
|
||||
style (str): Style name to apply.
|
||||
|
||||
Returns:
|
||||
None:
|
||||
"""
|
||||
length = len(self)
|
||||
if end < 0 or start > length:
|
||||
# span in range
|
||||
return
|
||||
self._spans.append(TextSpan(max(0, start), min(length, end), style))
|
||||
|
||||
def __console_render__(
|
||||
self, console: Console, options: ConsoleOptions
|
||||
) -> Iterable[StyledText]:
|
||||
"""Render the rich text to the console.
|
||||
|
||||
Args:
|
||||
console (Console): Console instance.
|
||||
options (ConsoleOptions): Console options.
|
||||
|
||||
Returns:
|
||||
Iterable[StyledText]: An iterable of styled text.
|
||||
"""
|
||||
|
||||
print(self._spans)
|
||||
text = self.text
|
||||
stack: List[Style] = []
|
||||
|
||||
get_style = console.get_style
|
||||
spans = [
|
||||
(span.start, True, get_style(span.style or "none")) for span in self._spans
|
||||
]
|
||||
spans.extend(
|
||||
(span.end, False, get_style(span.style or "none")) for span in self._spans
|
||||
)
|
||||
spans.sort(key=itemgetter(0))
|
||||
spans.insert(0, (0, True, get_style("none")))
|
||||
spans.append((len(text), False, get_style("none")))
|
||||
|
||||
null_style = Style()
|
||||
current_style = Style()
|
||||
start_spans = (
|
||||
(span.start, True, get_style(span.style) or null_style)
|
||||
for span in self._spans
|
||||
)
|
||||
end_spans = (
|
||||
(span.end, False, get_style(span.style) or null_style)
|
||||
for span in self._spans
|
||||
)
|
||||
|
||||
spans = [
|
||||
(0, True, null_style),
|
||||
*start_spans,
|
||||
*end_spans,
|
||||
(len(text), False, null_style),
|
||||
]
|
||||
spans.sort(key=itemgetter(0))
|
||||
|
||||
current_style = Style()
|
||||
for (offset, entering, style), (next_offset, _, _) in zip(spans, spans[1:]):
|
||||
style = style or null_style
|
||||
if entering:
|
||||
stack.append(style)
|
||||
current_style = current_style.apply(style)
|
||||
|
@ -113,7 +144,7 @@ class RichText:
|
|||
self._text.append(text)
|
||||
offset = len(self)
|
||||
text_length = len(text)
|
||||
self._spans.append(TextSpan(offset, offset + text_length, style))
|
||||
self._spans.append(TextSpan(offset, offset + text_length, style or "none"))
|
||||
self._length += text_length
|
||||
self._text_str = None
|
||||
|
||||
|
@ -131,7 +162,7 @@ class RichText:
|
|||
for offset, line in zip(offsets, new_lines):
|
||||
if span.end <= offset or span.start >= offset + len(line):
|
||||
continue
|
||||
line._spans.append(span.adjust_offset(-offset))
|
||||
line._spans.append(span.adjust_offset(-offset, len(line)))
|
||||
|
||||
return new_lines
|
||||
|
||||
|
|
Loading…
Reference in New Issue