Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Styled text wraps incorrectly after capture #2907

Closed
2 tasks
nedbat opened this issue Mar 27, 2023 · 5 comments
Closed
2 tasks

[BUG] Styled text wraps incorrectly after capture #2907

nedbat opened this issue Mar 27, 2023 · 5 comments

Comments

@nedbat
Copy link

nedbat commented Mar 27, 2023

Describe the bug

I have text with styling that can get long. When I use console.capture() and then later print it with console.print(), it's wrapped incorrectly. Using console.print() directly wraps it correctly.

Code:

import rich.console
import time

console = rich.console.Console(highlight=False)

STYLED = "[red]red[/] [blue]blue[/] [yellow]yellow[/] [white]white[/] "
LONG = (
    "lorem ipsum quia dolor sit amet consectetur adipisci velit, sed quia non "
    + "numquam eius modi tempora incidunt, ut labore et dolore magnam aliquam "
    + "quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem "
    + "ullam corporis suscipit laboriosam."
)

TEXT = STYLED * 10 + LONG

print("Plain:")
console.print(TEXT)

with console.capture() as capture:
    console.print(TEXT)
captured = capture.get()

print()
print("Captured:")
console.print(captured)

image

Platform

Click to expand

This is Mac using iTerm2. The result is the same using Terminal.

I may ask you to copy and paste the output of the following commands. It may save some time if you do it now.

If you're using Rich in a terminal:

python -m rich.diagnose
pip freeze | grep rich
% python -m rich.diagnose
╭───────────────────────── <class 'rich.console.Console'> ─────────────────────────╮
│ A high level console interface.                                                  │
│                                                                                  │
│ ╭──────────────────────────────────────────────────────────────────────────────╮ │
│ │ <console width=162 ColorSystem.TRUECOLOR>                                    │ │
│ ╰──────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                  │
│     color_system = 'truecolor'                                                   │
│         encoding = 'utf-8'                                                       │
│             file = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'> │
│           height = 40                                                            │
│    is_alt_screen = False                                                         │
│ is_dumb_terminal = False                                                         │
│   is_interactive = True                                                          │
│       is_jupyter = False                                                         │
│      is_terminal = True                                                          │
│   legacy_windows = False                                                         │
│         no_color = False                                                         │
│          options = ConsoleOptions(                                               │
│                        size=ConsoleDimensions(width=162, height=40),             │
│                        legacy_windows=False,                                     │
│                        min_width=1,                                              │
│                        max_width=162,                                            │
│                        is_terminal=True,                                         │
│                        encoding='utf-8',                                         │
│                        max_height=40,                                            │
│                        justify=None,                                             │
│                        overflow=None,                                            │
│                        no_wrap=False,                                            │
│                        highlight=None,                                           │
│                        markup=None,                                              │
│                        height=None                                               │
│                    )                                                             │
│            quiet = False                                                         │
│           record = False                                                         │
│         safe_box = True                                                          │
│             size = ConsoleDimensions(width=162, height=40)                       │
│        soft_wrap = False                                                         │
│           stderr = False                                                         │
│            style = None                                                          │
│         tab_size = 8                                                             │
│            width = 162                                                           │
╰──────────────────────────────────────────────────────────────────────────────────╯
╭─── <class 'rich._windows.WindowsConsoleFeatures'> ────╮
│ Windows features available.                           │
│                                                       │
│ ╭───────────────────────────────────────────────────╮ │
│ │ WindowsConsoleFeatures(vt=False, truecolor=False) │ │
│ ╰───────────────────────────────────────────────────╯ │
│                                                       │
│ truecolor = False                                     │
│        vt = False                                     │
╰───────────────────────────────────────────────────────╯
╭─────── Environment Variables ────────╮
│ {                                    │
│     'TERM': 'xterm-256color-italic', │
│     'COLORTERM': 'truecolor',        │
│     'CLICOLOR': '1',                 │
│     'NO_COLOR': None,                │
│     'TERM_PROGRAM': 'iTerm.app',     │
│     'COLUMNS': None,                 │
│     'LINES': None,                   │
│     'JUPYTER_COLUMNS': None,         │
│     'JUPYTER_LINES': None,           │
│     'JPY_PARENT_PID': None,          │
│     'VSCODE_VERBOSE_LOGGING': None   │
│ }                                    │
╰──────────────────────────────────────╯
platform="Darwin"

% pip freeze | grep rich
rich==13.3.3
@willmcgugan
Copy link
Collaborator

The escape sequences in the captured text break wrapping / formatting. They may also interfere with any additional styles you apply.

You should find that if you use a plain old print or write to stdout you will get the results you expect.

You could also use Text.from_ansi, which parses those escape sequences to allow them to be reprinted or manipulated:

console.print(Text.from_ansi(captured))

This isn't done by default, because it costs a little cpu and there are some situations where you really want those escape sequences to be written out unmodified.

@Textualize Textualize deleted a comment from github-actions bot Mar 27, 2023
@nedbat
Copy link
Author

nedbat commented Mar 27, 2023

Thanks. I my project (https://github.com/nedbat/watchgha) I'm using console.screen:

            with console.screen() as screen:
                while not done:
                    screen.update(output)
                    time.sleep(1)

which wraps output incorrectly. If I replace screen.update with print(output), the wrapping is gone, but now it doesn't clear and redraw the screen properly. I'm missing something about how these facilities interact.

@willmcgugan
Copy link
Collaborator

What was the reasoning behind capturing the output? You can pass any renderable to screen.update and it should display in the same way as if you had done console.print.

@nedbat
Copy link
Author

nedbat commented Mar 27, 2023

I wanted to get the latest output and then either display it on the alternate screen, or straight to the console, depending on if it was the last update (done == True). Text.from_ansi works for me, but I think I will change the code to return a plain string with markup. I'm understanding more, thanks.

@nedbat nedbat closed this as completed Mar 27, 2023
@github-actions
Copy link

I hope we solved your problem.

If you like using Rich, you might also enjoy Textual

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants