diff --git a/redbot/core/utils/chat_formatting.py b/redbot/core/utils/chat_formatting.py index 9a96ae380c6..9c1f6684953 100644 --- a/redbot/core/utils/chat_formatting.py +++ b/redbot/core/utils/chat_formatting.py @@ -4,12 +4,13 @@ import itertools import math import textwrap -from io import BytesIO -from typing import Iterator, List, Literal, Optional, Sequence, SupportsInt, Union +from io import BytesIO, StringIO +from typing import Any, Iterator, List, Literal, Optional, Sequence, SupportsInt, Union import discord from babel.lists import format_list as babel_list from babel.numbers import format_decimal +from rich.console import Console from redbot.core.i18n import Translator, get_babel_locale, get_babel_regional_format @@ -729,3 +730,66 @@ def text_to_file( """ file = BytesIO(text.encode(encoding)) return discord.File(file, filename, spoiler=spoiler) + + +def rich_markup( + *objects: Any, + crop: Optional[bool] = True, + emoji: Optional[bool] = True, + highlight: Optional[bool] = True, + justify: Optional[str] = None, + markup: Optional[bool] = True, + no_wrap: Optional[bool] = None, + overflow: Optional[str] = None, + width: Optional[int] = None, +) -> str: + """Returns a codeblock with ANSI formatting for colour support. + + This supports a limited set of Rich markup, and rich helper functions. (https://rich.readthedocs.io/en/stable/index.html) + + Parameters + ---------- + *objects: Any + The text to convert to ANSI formatting. + crop: Optional[bool] + Crop output to width of virtual terminal. Defaults to ``True``. + emoji: Optional[bool] + Enable emoji code. Defaults to ``True``. + highlight: Optional[bool] + Enable automated highlighting. Defaults to ``True``. + justify: Optional[str] + Justify method: "default", "left", "right", "center", or "full". Defaults to ``None``. + markup: Optional[bool] + Boolean to enable Console Markup. Defaults to ``True``. + no_wrap: Optional[bool] + Disables word wrapping. Defaults to ``None``. + overflow: Optional[str] + Overflow method: "ignore", "crop", "fold", or "ellipsis". Defaults to None. + width: Optional[int] + The width of the virtual terminal. Defaults to ``80`` characters long. + + + Returns + ------- + str: + The ANSI formatted text in a codeblock. + """ + temp_console = Console( # Prevent messing with STDOUT's console + color_system="standard", # Discord only supports 8-bit in colors + emoji=emoji, + file=StringIO(), + force_terminal=True, + force_interactive=False, + highlight=highlight, + markup=markup, + width=width if width is not None else 80, + ) + + temp_console.print( + *objects, + crop=crop, + justify=justify, + no_wrap=no_wrap, + overflow=overflow, + ) + return box(temp_console.file.getvalue(), lang="ansi")