def test_style_output():
"""Test that *style_output()* styles output."""
class CliStyle(Style):
default_style = ""
styles = {
Token.Output.Header: 'bold #ansired',
Token.Output.OddRow: 'bg:#eee #111',
Token.Output.EvenRow: '#0f0'
}
headers = ['h1', 'h2']
data = [['??', '2'], ['????????', 'b']]
expected_headers = ['\x1b[31;01mh1\x1b[39;00m', '\x1b[31;01mh2\x1b[39;00m']
expected_data = [['\x1b[38;5;233;48;5;7m??\x1b[39;49m',
'\x1b[38;5;233;48;5;7m2\x1b[39;49m'],
['\x1b[38;5;10m????????\x1b[39m', '\x1b[38;5;10mb\x1b[39m']]
results = style_output(data, headers, style=CliStyle)
assert (expected_data, expected_headers) == (list(results[0]), results[1])
python类Style()的实例源码
def test_style_output_with_newlines():
"""Test that *style_output()* styles output with newlines in it."""
class CliStyle(Style):
default_style = ""
styles = {
Token.Output.Header: 'bold #ansired',
Token.Output.OddRow: 'bg:#eee #111',
Token.Output.EvenRow: '#0f0'
}
headers = ['h1', 'h2']
data = [['??\nLine2', '????????']]
expected_headers = ['\x1b[31;01mh1\x1b[39;00m', '\x1b[31;01mh2\x1b[39;00m']
expected_data = [
['\x1b[38;5;233;48;5;7m??\x1b[39;49m\n\x1b[38;5;233;48;5;7m'
'Line2\x1b[39;49m',
'\x1b[38;5;233;48;5;7m????????\x1b[39;49m']]
results = style_output(data, headers, style=CliStyle)
assert (expected_data, expected_headers) == (list(results[0]), results[1])
def test_style_output_custom_tokens():
"""Test that *style_output()* styles output with custom token names."""
class CliStyle(Style):
default_style = ""
styles = {
Token.Results.Headers: 'bold #ansired',
Token.Results.OddRows: 'bg:#eee #111',
Token.Results.EvenRows: '#0f0'
}
headers = ['h1', 'h2']
data = [['1', '2'], ['a', 'b']]
expected_headers = ['\x1b[31;01mh1\x1b[39;00m', '\x1b[31;01mh2\x1b[39;00m']
expected_data = [['\x1b[38;5;233;48;5;7m1\x1b[39;49m',
'\x1b[38;5;233;48;5;7m2\x1b[39;49m'],
['\x1b[38;5;10ma\x1b[39m', '\x1b[38;5;10mb\x1b[39m']]
output = style_output(
data, headers, style=CliStyle,
header_token='Token.Results.Headers',
odd_row_token='Token.Results.OddRows',
even_row_token='Token.Results.EvenRows')
assert (expected_data, expected_headers) == (list(output[0]), output[1])
def style_from_pygments(pygments_style_cls=None):
"""
Shortcut to create a :class:`.Style` instance from a Pygments style class
and a style dictionary.
Example::
from prompt_toolkit.styles.from_pygments import style_from_pygments
from pygments.styles import get_style_by_name
style = style_from_pygments(get_style_by_name('monokai'))
:param pygments_style_cls: Pygments style class to start from.
"""
# Import inline.
from pygments.style import Style as pygments_Style
assert issubclass(pygments_style_cls, pygments_Style)
pygments_style = []
if pygments_style_cls is not None:
for token, style in pygments_style_cls.styles.items():
pygments_style.append((_pygments_token_to_classname(token), style))
return Style(pygments_style)
def style_from_pygments(style_cls=pygments_DefaultStyle,
style_dict=None,
include_defaults=True):
"""
Shortcut to create a :class:`.Style` instance from a Pygments style class
and a style dictionary.
:param style_cls: Pygments style class to start from.
:param style_dict: Dictionary for this style. `{Token: style}`.
:param include_defaults: (`bool`) Include prompt_toolkit extensions.
"""
assert style_dict is None or isinstance(style_dict, dict)
assert style_cls is None or issubclass(style_cls, pygments_Style)
styles_dict = {}
if style_cls is not None:
styles_dict.update(style_cls.styles)
if style_dict is not None:
styles_dict.update(style_dict)
return style_from_dict(styles_dict, include_defaults=include_defaults)
def style_from_pygments(style_cls=pygments_DefaultStyle,
style_dict=None,
include_defaults=True):
"""
Shortcut to create a :class:`.Style` instance from a Pygments style class
and a style dictionary.
Example::
from prompt_toolkit.styles.from_pygments import style_from_pygments
from pygments.styles import get_style_by_name
style = style_from_pygments(get_style_by_name('monokai'))
:param style_cls: Pygments style class to start from.
:param style_dict: Dictionary for this style. `{Token: style}`.
:param include_defaults: (`bool`) Include prompt_toolkit extensions.
"""
assert style_dict is None or isinstance(style_dict, dict)
assert style_cls is None or issubclass(style_cls, pygments_Style)
styles_dict = {}
if style_cls is not None:
styles_dict.update(style_cls.styles)
if style_dict is not None:
styles_dict.update(style_dict)
return style_from_dict(styles_dict, include_defaults=include_defaults)
def __new__(cls, pygments_style_cls):
assert issubclass(pygments_style_cls, pygments_Style)
return style_from_dict(pygments_style_cls.styles)
def style_from_pygments(style_cls=pygments_DefaultStyle,
style_dict=None,
include_defaults=True):
"""
Shortcut to create a :class:`.Style` instance from a Pygments style class
and a style dictionary.
Example::
from prompt_toolkit.styles.from_pygments import style_from_pygments
from pygments.styles import get_style_by_name
style = style_from_pygments(get_style_by_name('monokai'))
:param style_cls: Pygments style class to start from.
:param style_dict: Dictionary for this style. `{Token: style}`.
:param include_defaults: (`bool`) Include prompt_toolkit extensions.
"""
assert style_dict is None or isinstance(style_dict, dict)
assert style_cls is None or issubclass(style_cls, pygments_Style)
styles_dict = {}
if style_cls is not None:
styles_dict.update(style_cls.styles)
if style_dict is not None:
styles_dict.update(style_dict)
return style_from_dict(styles_dict, include_defaults=include_defaults)
def __new__(cls, pygments_style_cls):
assert issubclass(pygments_style_cls, pygments_Style)
return style_from_dict(pygments_style_cls.styles)
def style_from_pygments(style_cls=pygments_DefaultStyle,
style_dict=None,
include_defaults=True):
"""
Shortcut to create a :class:`.Style` instance from a Pygments style class
and a style dictionary.
Example::
from prompt_toolkit.styles.from_pygments import style_from_pygments
from pygments.styles import get_style_by_name
style = style_from_pygments(get_style_by_name('monokai'))
:param style_cls: Pygments style class to start from.
:param style_dict: Dictionary for this style. `{Token: style}`.
:param include_defaults: (`bool`) Include prompt_toolkit extensions.
"""
assert style_dict is None or isinstance(style_dict, dict)
assert style_cls is None or issubclass(style_cls, pygments_Style)
styles_dict = {}
if style_cls is not None:
styles_dict.update(style_cls.styles)
if style_dict is not None:
styles_dict.update(style_dict)
return style_from_dict(styles_dict, include_defaults=include_defaults)
def __new__(cls, pygments_style_cls):
assert issubclass(pygments_style_cls, pygments_Style)
return style_from_dict(pygments_style_cls.styles)
def _get_prompt_tokens_and_style(self):
"""Returns function to pass as prompt to prompt_toolkit."""
token_names, cstyles, strings = format_prompt_for_prompt_toolkit(self.prompt)
tokens = [getattr(Token, n) for n in token_names]
def get_tokens(cli):
return list(zip(tokens, strings))
class CustomStyle(Style):
styles = {
Token.Menu.Completions.Completion.Current: 'bg:#00aaaa #000000',
Token.Menu.Completions.Completion: 'bg:#008888 #ffffff',
Token.Menu.Completions.Meta.Current: 'bg:#00aaaa #000000',
Token.Menu.Completions.Meta: 'bg:#00aaaa #ffffff',
Token.Menu.Completions.ProgressButton: 'bg:#003333',
Token.Menu.Completions.ProgressBar: 'bg:#00aaaa',
Token.Toolbar: 'bg:#222222 #cccccc',
Token.Scrollbar: 'bg:#00aaaa',
Token.Scrollbar.Button: 'bg:#003333',
Token.Toolbar.Off: 'bg:#222222 #696969',
Token.Toolbar.On: 'bg:#222222 #ffffff',
Token.Toolbar.Search: 'noinherit bold',
Token.Toolbar.Search.Text: 'nobold',
Token.Toolbar.System: 'noinherit bold',
Token.Toolbar.Arg: 'noinherit bold',
Token.Toolbar.Arg.Text: 'nobold',
Token.AutoSuggestion: '#666666',
Token.Aborted: '#888888',
}
# update with the prompt styles
styles.update({t: s for (t, s) in zip(tokens, cstyles)})
# Update with with any user styles
userstyle = builtins.__xonsh_env__.get('PROMPT_TOOLKIT_STYLES')
if userstyle is not None:
styles.update(userstyle)
return get_tokens, CustomStyle
def __new__(cls, pygments_style_cls):
assert issubclass(pygments_style_cls, pygments_Style)
return style_from_dict(pygments_style_cls.styles)
def style_from_pygments(style_cls=pygments_DefaultStyle,
style_dict=None,
include_defaults=True):
"""
Shortcut to create a :class:`.Style` instance from a Pygments style class
and a style dictionary.
Example::
from prompt_toolkit.styles.from_pygments import style_from_pygments
from pygments.styles import get_style_by_name
style = style_from_pygments(get_style_by_name('monokai'))
:param style_cls: Pygments style class to start from.
:param style_dict: Dictionary for this style. `{Token: style}`.
:param include_defaults: (`bool`) Include prompt_toolkit extensions.
"""
assert style_dict is None or isinstance(style_dict, dict)
assert style_cls is None or issubclass(style_cls, pygments_Style)
styles_dict = {}
if style_cls is not None:
styles_dict.update(style_cls.styles)
if style_dict is not None:
styles_dict.update(style_dict)
return style_from_dict(styles_dict, include_defaults=include_defaults)
def __new__(cls, pygments_style_cls):
assert issubclass(pygments_style_cls, pygments_Style)
return style_from_dict(pygments_style_cls.styles)
def style_output(data, headers, style=None,
header_token='Token.Output.Header',
odd_row_token='Token.Output.OddRow',
even_row_token='Token.Output.EvenRow', **_):
"""Style the *data* and *headers* (e.g. bold, italic, and colors)
.. NOTE::
This requires the `Pygments <http://pygments.org/>`_ library to
be installed. You can install it with CLI Helpers as an extra::
$ pip install cli_helpers[styles]
Example usage::
from cli_helpers.tabular_output.preprocessors import style_output
from pygments.style import Style
from pygments.token import Token
class YourStyle(Style):
default_style = ""
styles = {
Token.Output.Header: 'bold #ansired',
Token.Output.OddRow: 'bg:#eee #111',
Token.Output.EvenRow: '#0f0'
}
headers = ('First Name', 'Last Name')
data = [['Fred', 'Roberts'], ['George', 'Smith']]
data, headers = style_output(data, headers, style=YourStyle)
:param iterable data: An :term:`iterable` (e.g. list) of rows.
:param iterable headers: The column headers.
:param str/pygments.style.Style style: A Pygments style. You can `create
your own styles <http://pygments.org/docs/styles/#creating-own-styles>`_.
:param str header_token: The token type to be used for the headers.
:param str odd_row_token: The token type to be used for odd rows.
:param str even_row_token: The token type to be used for even rows.
:return: The styled data and headers.
:rtype: tuple
"""
if style and HAS_PYGMENTS:
formatter = Terminal256Formatter(style=style)
def style_field(token, field):
"""Get the styled text for a *field* using *token* type."""
s = StringIO()
formatter.format(((token, field),), s)
return s.getvalue()
headers = [style_field(header_token, header) for header in headers]
data = ([style_field(odd_row_token if i % 2 else even_row_token, f)
for f in r] for i, r in enumerate(data, 1))
return iter(data), headers