Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_ansi_wrap(self):
"""Test :func:`humanfriendly.terminal.ansi_wrap()`."""
text = "Whatever"
# Make sure ansi_wrap() does nothing when no keyword arguments are given.
assert text == ansi_wrap(text)
# Make sure ansi_wrap() starts the text with the CSI sequence.
assert ansi_wrap(text, bold=True).startswith(ANSI_CSI)
# Make sure ansi_wrap() ends the text by resetting the ANSI styles.
assert ansi_wrap(text, bold=True).endswith(ANSI_RESET)
def test_ansi_width(self):
"""Test :func:`humanfriendly.terminal.ansi_width()`."""
text = "Whatever"
# Make sure ansi_width() works as expected on strings without ANSI escape sequences.
assert len(text) == ansi_width(text)
# Wrap a text in ANSI escape sequences and make sure ansi_width() treats it as expected.
wrapped = ansi_wrap(text, bold=True)
# Make sure ansi_wrap() changed the text.
assert wrapped != text
# Make sure ansi_wrap() added additional bytes.
assert len(wrapped) > len(text)
# Make sure the result of ansi_width() stays the same.
assert len(text) == ansi_width(wrapped)
def test_html_conversion(self):
"""Check the conversion from ANSI escape sequences to HTML."""
# Check conversion of colored text.
for color_name, ansi_code in ANSI_COLOR_CODES.items():
ansi_encoded_text = 'plain text followed by %s text' % ansi_wrap(color_name, color=color_name)
expected_html = format(
'<code>plain text followed by <span style="color:{css}">{name}</span> text</code>',
css=EIGHT_COLOR_PALETTE[ansi_code], name=color_name,
)
self.assertEqual(expected_html, convert(ansi_encoded_text))
# Check conversion of bright colored text.
expected_html = '<code><span style="color:#FF0">bright yellow</span></code>'
self.assertEqual(expected_html, convert(ansi_wrap('bright yellow', color='yellow', bright=True)))
# Check conversion of text with a background color.
expected_html = '<code><span style="background-color:#DE382B">red background</span></code>'
self.assertEqual(expected_html, convert(ansi_wrap('red background', background='red')))
# Check conversion of text with a bright background color.
expected_html = '<code><span style="background-color:#F00">bright red background</span></code>'
self.assertEqual(expected_html, convert(ansi_wrap('bright red background', background='red', bright=True)))
# Check conversion of text that uses the 256 color mode palette as a foreground color.
expected_html = '<code><span style="color:#FFAF00">256 color mode foreground</span></code>'
self.assertEqual(expected_html, convert(ansi_wrap('256 color mode foreground', color=214)))
# Check conversion of text that uses the 256 color mode palette as a background color.
expected_html = '<code><span style="background-color:#AF0000">256 color mode background</span></code>'
self.assertEqual(expected_html, convert(ansi_wrap('256 color mode background', background=124)))
# Check that invalid 256 color mode indexes don't raise exceptions.
expected_html = '<code>plain text expected</code>'
self.assertEqual(expected_html, convert('\x1b[38;5;256mplain text expected\x1b[0m'))
# Check conversion of bold text.
The default field styles (:data:`DEFAULT_FIELD_STYLES`) define a style for the
`name` field but not for the `process` field, however because both fields
are part of the same whitespace delimited token they'll be highlighted
together in the style defined for the `name` field.
"""
result = []
parser = FormatStringParser(style=style)
for group in parser.get_grouped_pairs(fmt):
applicable_styles = [self.nn.get(self.field_styles, token.name) for token in group if token.name]
if sum(map(bool, applicable_styles)) == 1:
# If exactly one (1) field style is available for the group of
# tokens then all of the tokens will be styled the same way.
# This provides a limited form of backwards compatibility with
# the (intended) behavior of coloredlogs before the release of
# version 10.
result.append(ansi_wrap(
''.join(token.text for token in group),
**next(s for s in applicable_styles if s)
))
else:
for token in group:
text = token.text
if token.name:
field_styles = self.nn.get(self.field_styles, token.name)
if field_styles:
text = ansi_wrap(text, **field_styles)
result.append(text)
return ''.join(result)
# If exactly one (1) field style is available for the group of
# tokens then all of the tokens will be styled the same way.
# This provides a limited form of backwards compatibility with
# the (intended) behavior of coloredlogs before the release of
# version 10.
result.append(ansi_wrap(
''.join(token.text for token in group),
**next(s for s in applicable_styles if s)
))
else:
for token in group:
text = token.text
if token.name:
field_styles = self.nn.get(self.field_styles, token.name)
if field_styles:
text = ansi_wrap(text, **field_styles)
result.append(text)
return ''.join(result)
def prepare_prompt_text(prompt_text, **options):
"""
Wrap a text to be rendered as an interactive prompt in ANSI escape sequences.
:param prompt_text: The text to render on the prompt (a string).
:param options: Any keyword arguments are passed on to :func:`.ansi_wrap()`.
:returns: The resulting prompt text (a string).
ANSI escape sequences are only used when the standard output stream is
connected to a terminal. When the standard input stream is connected to a
terminal any escape sequences are wrapped in "readline hints".
"""
return (ansi_wrap(prompt_text, readline_hints=connected_to_terminal(sys.stdin), **options)
if terminal_supports_colors(sys.stdout)
else prompt_text)
- Short and long command line options
- Environment variables
- Meta variables (see :func:`find_meta_variables()`)
All items are highlighted in the color defined by
:data:`.HIGHLIGHT_COLOR`.
"""
# Ugly workaround to avoid circular import errors due to interdependencies
# between the humanfriendly.terminal and humanfriendly.usage modules.
from humanfriendly.terminal import ansi_wrap, HIGHLIGHT_COLOR
formatted_lines = []
meta_variables = find_meta_variables(usage_text)
for line in usage_text.strip().splitlines(True):
if line.startswith(USAGE_MARKER):
# Highlight the "Usage: ..." line in bold font and color.
formatted_lines.append(ansi_wrap(line, color=HIGHLIGHT_COLOR))
else:
# Highlight options, meta variables and environment variables.
formatted_lines.append(replace_special_tokens(
line, meta_variables,
lambda token: ansi_wrap(token, color=HIGHLIGHT_COLOR),
))
return ''.join(formatted_lines)