rich icon indicating copy to clipboard operation
rich copied to clipboard

[BUG] Link to local files with spaces in their path don't render in Console

Open jfthuong opened this issue 2 years ago • 4 comments

  • [x] I've checked docs and closed issues for possible solutions.
  • [x] I can't find my issue in the FAQ.

Describe the bug

When using [link=<link>]<text>[/link] to display a link in the console, it works well with local files except when these files have a space in it.

  1. By default, the console will not apply the link Style (the code does not enter in Style.parse for this)
  2. If we pass a URI (e.g. file://my%20F/my%20Ffile.txt), then rich replace %20F by %25F20F making the link unusable
from rich.console import Console


path_without = r"D:\TOTO\my_dir\animals.txt"
path_with = r"D:\TOTO\my_dir\file with space.txt"
uri = "file://" + path_with.replace(" ", "%20F").replace("\\", "/")
print(f"{uri=}")

console = Console()
console.print(f"Link #0: [link={path_without}]Local Path without space[/link]")
console.print(f"Link #1: [link={path_with}]Local Path with space[/link]")
console.print(
    f"Link #2: [link={uri}]Local path with space as URI[/link] (including %20F)"
)

image

Platform

Windows 11, Python 3.9, CMD & Powershell
What platform (Win/Linux/Mac) are you running on? What terminal software are you using? ``` ╭───────────────────────── ─────────────────────────╮ │ A high level console interface. │ │ │ │ ╭──────────────────────────────────────────────────────────────────────────────╮ │ │ │ │ │ │ ╰──────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ color_system = 'truecolor' │ │ encoding = 'utf-8' │ │ file = <_io.textiowrapper name="<stdout>" mode="w" encoding="utf-8"> │ │ height = 35 │ │ 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=116, height=35), │ │ legacy_windows=False, │ │ min_width=1, │ │ max_width=116, │ │ is_terminal=True, │ │ encoding='utf-8', │ │ max_height=35, │ │ justify=None, │ │ overflow=None, │ │ no_wrap=False, │ │ highlight=None, │ │ markup=None, │ │ height=None │ │ ) │ │ quiet = False │ │ record = False │ │ safe_box = True │ │ size = ConsoleDimensions(width=116, height=35) │ │ soft_wrap = False │ │ stderr = False │ │ style = None │ │ tab_size = 8 │ │ width = 116 │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭── ───╮ │ Windows features available. │ │ │ │ ╭─────────────────────────────────────────────────╮ │ │ │ WindowsConsoleFeatures(vt=True, truecolor=True) │ │ │ ╰─────────────────────────────────────────────────╯ │ │ │ │ truecolor = True │ │ vt = True │ ╰─────────────────────────────────────────────────────╯ ╭────── Environment Variables ───────╮ │ { │ │ 'TERM': None, │ │ 'COLORTERM': None, │ │ 'CLICOLOR': None, │ │ 'NO_COLOR': None, │ │ 'TERM_PROGRAM': None, │ │ 'COLUMNS': None, │ │ 'LINES': None, │ │ 'JUPYTER_COLUMNS': None, │ │ 'JUPYTER_LINES': None, │ │ 'JPY_PARENT_PID': None, │ │ 'VSCODE_VERBOSE_LOGGING': None │ │ } │ ╰────────────────────────────────────╯ platform="Windows" ```

jfthuong avatar Sep 28 '23 06:09 jfthuong

Thank you for your issue. Give us a little time to review it.

PS. You might want to check the FAQ if you haven't done so already.

This is an automated reply, generated by FAQtory

github-actions[bot] avatar Sep 28 '23 06:09 github-actions[bot]

If we pass a URI (e.g. file://my%20F/my%20Ffile.txt), then rich replace %20F by %25F20F making the link unusable

I think it is Windows rather than Rich doing this extra encoding, for what it's worth.

from rich.console import Console
from rich.text import Text

text_with_encoding = r"foo%20bar%20baz"
rich_text = Text.from_markup(f"[link={text_with_encoding}]Text with encoding[/link]")

path_with_encoding = r"C:\Users\Tom\Documents\New%20Text%20Document.txt"
rich_path = Text.from_markup(f"[link={path_with_encoding}]Path with encoding[/link]")

console = Console()
console.print(rich_text)
console.print(rich_text.get_style_at_offset(console, 0))

console.print(rich_path)
console.print(rich_path.get_style_at_offset(console, 0))

TomJGooding avatar Sep 29 '23 10:09 TomJGooding