Merge pull request #1706 from 0xDEC0DE/issue/1670

Add a Text.from_ansi helper method
This commit is contained in:
Will McGugan 2021-11-28 16:04:03 +00:00 committed by GitHub
commit a6d1d78487
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 0 deletions

View file

@ -40,6 +40,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Allowed `__rich__` to work recursively
- Allowed Text classes to work with sep in print https://github.com/willmcgugan/rich/issues/1689
### Added
- Added a `rich.text.Text.from_ansi` helper method for handling pre-formatted input strings https://github.com/willmcgugan/rich/issues/1670
## [10.13.0] - 2021-11-07
### Added

View file

@ -23,4 +23,5 @@ The following people have contributed to the development of Rich:
- [Clément Robert](https://github.com/neutrinoceros)
- [Tushar Sadhwani](https://github.com/tusharsadhwani)
- [Tim Savage](https://github.com/timsavage)
- [Nicolas Simonds](https://github.com/0xDEC0DE)
- [Gabriele N. Tornetta](https://github.com/p403n1x87)

View file

@ -26,6 +26,11 @@ Alternatively, you can construct styled text by calling :meth:`~rich.text.Text.a
text.append(" World!")
console.print(text)
If you would like to use text that is already formatted with ANSI codes, call :meth:`~rich.text.Text.from_ansi` to convert it to a ``Text`` object:
text = Text.from_ansi("\033[1mHello, World!\033[0m")
console.print(text.spans)
Since building Text instances from parts is a common requirement, Rich offers :meth:`~rich.text.Text.assemble` which will combine strings or pairs of string and Style, and return a Text instance. The follow example is equivalent to the code above::
text = Text.assemble(("Hello", "bold magenta"), " World!")

View file

@ -242,6 +242,40 @@ class Text(JupyterMixin):
rendered_text.overflow = overflow
return rendered_text
@classmethod
def from_ansi(
cls,
text: str,
*,
style: Union[str, Style] = "",
justify: Optional["JustifyMethod"] = None,
overflow: Optional["OverflowMethod"] = None,
no_wrap: Optional[bool] = None,
end: str = "\n",
tab_size: Optional[int] = 8,
) -> "Text":
"""Create a Text object from pre-formatted ANSI.
Args:
text (str): A string containing ANSI color codes.
style (Union[str, Style], optional): Base style for text. Defaults to "".
justify (str, optional): Justify method: "left", "center", "full", "right". Defaults to None.
overflow (str, optional): Overflow method: "crop", "fold", "ellipsis". Defaults to None.
no_wrap (bool, optional): Disable text wrapping, or None for default. Defaults to None.
end (str, optional): Character to end text with. Defaults to "\\\\n".
tab_size (int): Number of spaces per tab, or ``None`` to use ``console.tab_size``. Defaults to 8.
"""
from .ansi import AnsiDecoder
decoded_text = AnsiDecoder().decode_line(text)
decoded_text.justify = justify
decoded_text.overflow = overflow
decoded_text.no_wrap = no_wrap
decoded_text.end = end
decoded_text.tab_size = tab_size
decoded_text.stylize(style)
return decoded_text
@classmethod
def styled(
cls,

View file

@ -95,6 +95,15 @@ def test_from_markup():
assert text._spans == [Span(7, 13, "bold")]
def test_from_ansi():
text = Text.from_ansi("Hello, \033[1mWorld!\033[0m")
text2 = Text.from_ansi("Hello, \033[1mWorld!\033[0m", style="red")
assert str(text) == "Hello, World!"
assert text._spans == [Span(7, 13, Style(bold=True))]
assert str(text2) == "Hello, World!"
assert text2._spans == [Span(7, 13, Style(bold=True)), Span(0, 13, "red")]
def test_copy():
test = Text()
test.append("Hello", "bold")