diff --git a/CHANGELOG.md b/CHANGELOG.md index d9241fad..d07ebde9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added width option to Panel - Change special method `__render_width__` to `__measure__` - Dropped the "markdown style" syntax in console markup +- Optimized style rendering ### Added diff --git a/rich/_make_style_table.py b/rich/_make_style_table.py new file mode 100644 index 00000000..4a1e227a --- /dev/null +++ b/rich/_make_style_table.py @@ -0,0 +1,18 @@ +"""Generate a ANSI style table.""" + + +def make_table(): + table = [] + for attributes in range(0, 512): + ansi_codes = [] + for bit_no in range(0, 9): + bit = 1 << bit_no + if attributes & bit: + ansi_codes.append(str(1 + bit_no)) + table.append(";".join(ansi_codes)) + return table + + +table = make_table() +print(repr(table)) + diff --git a/rich/_style_table.py b/rich/_style_table.py new file mode 100644 index 00000000..cbdae695 --- /dev/null +++ b/rich/_style_table.py @@ -0,0 +1,517 @@ +# Generated by _make_style_table +# Maps a bit-field of attributes on to ANSI codes +STYLE_TABLE = [ + "", + "1", + "2", + "1;2", + "3", + "1;3", + "2;3", + "1;2;3", + "4", + "1;4", + "2;4", + "1;2;4", + "3;4", + "1;3;4", + "2;3;4", + "1;2;3;4", + "5", + "1;5", + "2;5", + "1;2;5", + "3;5", + "1;3;5", + "2;3;5", + "1;2;3;5", + "4;5", + "1;4;5", + "2;4;5", + "1;2;4;5", + "3;4;5", + "1;3;4;5", + "2;3;4;5", + "1;2;3;4;5", + "6", + "1;6", + "2;6", + "1;2;6", + "3;6", + "1;3;6", + "2;3;6", + "1;2;3;6", + "4;6", + "1;4;6", + "2;4;6", + "1;2;4;6", + "3;4;6", + "1;3;4;6", + "2;3;4;6", + "1;2;3;4;6", + "5;6", + "1;5;6", + "2;5;6", + "1;2;5;6", + "3;5;6", + "1;3;5;6", + "2;3;5;6", + "1;2;3;5;6", + "4;5;6", + "1;4;5;6", + "2;4;5;6", + "1;2;4;5;6", + "3;4;5;6", + "1;3;4;5;6", + "2;3;4;5;6", + "1;2;3;4;5;6", + "7", + "1;7", + "2;7", + "1;2;7", + "3;7", + "1;3;7", + "2;3;7", + "1;2;3;7", + "4;7", + "1;4;7", + "2;4;7", + "1;2;4;7", + "3;4;7", + "1;3;4;7", + "2;3;4;7", + "1;2;3;4;7", + "5;7", + "1;5;7", + "2;5;7", + "1;2;5;7", + "3;5;7", + "1;3;5;7", + "2;3;5;7", + "1;2;3;5;7", + "4;5;7", + "1;4;5;7", + "2;4;5;7", + "1;2;4;5;7", + "3;4;5;7", + "1;3;4;5;7", + "2;3;4;5;7", + "1;2;3;4;5;7", + "6;7", + "1;6;7", + "2;6;7", + "1;2;6;7", + "3;6;7", + "1;3;6;7", + "2;3;6;7", + "1;2;3;6;7", + "4;6;7", + "1;4;6;7", + "2;4;6;7", + "1;2;4;6;7", + "3;4;6;7", + "1;3;4;6;7", + "2;3;4;6;7", + "1;2;3;4;6;7", + "5;6;7", + "1;5;6;7", + "2;5;6;7", + "1;2;5;6;7", + "3;5;6;7", + "1;3;5;6;7", + "2;3;5;6;7", + "1;2;3;5;6;7", + "4;5;6;7", + "1;4;5;6;7", + "2;4;5;6;7", + "1;2;4;5;6;7", + "3;4;5;6;7", + "1;3;4;5;6;7", + "2;3;4;5;6;7", + "1;2;3;4;5;6;7", + "8", + "1;8", + "2;8", + "1;2;8", + "3;8", + "1;3;8", + "2;3;8", + "1;2;3;8", + "4;8", + "1;4;8", + "2;4;8", + "1;2;4;8", + "3;4;8", + "1;3;4;8", + "2;3;4;8", + "1;2;3;4;8", + "5;8", + "1;5;8", + "2;5;8", + "1;2;5;8", + "3;5;8", + "1;3;5;8", + "2;3;5;8", + "1;2;3;5;8", + "4;5;8", + "1;4;5;8", + "2;4;5;8", + "1;2;4;5;8", + "3;4;5;8", + "1;3;4;5;8", + "2;3;4;5;8", + "1;2;3;4;5;8", + "6;8", + "1;6;8", + "2;6;8", + "1;2;6;8", + "3;6;8", + "1;3;6;8", + "2;3;6;8", + "1;2;3;6;8", + "4;6;8", + "1;4;6;8", + "2;4;6;8", + "1;2;4;6;8", + "3;4;6;8", + "1;3;4;6;8", + "2;3;4;6;8", + "1;2;3;4;6;8", + "5;6;8", + "1;5;6;8", + "2;5;6;8", + "1;2;5;6;8", + "3;5;6;8", + "1;3;5;6;8", + "2;3;5;6;8", + "1;2;3;5;6;8", + "4;5;6;8", + "1;4;5;6;8", + "2;4;5;6;8", + "1;2;4;5;6;8", + "3;4;5;6;8", + "1;3;4;5;6;8", + "2;3;4;5;6;8", + "1;2;3;4;5;6;8", + "7;8", + "1;7;8", + "2;7;8", + "1;2;7;8", + "3;7;8", + "1;3;7;8", + "2;3;7;8", + "1;2;3;7;8", + "4;7;8", + "1;4;7;8", + "2;4;7;8", + "1;2;4;7;8", + "3;4;7;8", + "1;3;4;7;8", + "2;3;4;7;8", + "1;2;3;4;7;8", + "5;7;8", + "1;5;7;8", + "2;5;7;8", + "1;2;5;7;8", + "3;5;7;8", + "1;3;5;7;8", + "2;3;5;7;8", + "1;2;3;5;7;8", + "4;5;7;8", + "1;4;5;7;8", + "2;4;5;7;8", + "1;2;4;5;7;8", + "3;4;5;7;8", + "1;3;4;5;7;8", + "2;3;4;5;7;8", + "1;2;3;4;5;7;8", + "6;7;8", + "1;6;7;8", + "2;6;7;8", + "1;2;6;7;8", + "3;6;7;8", + "1;3;6;7;8", + "2;3;6;7;8", + "1;2;3;6;7;8", + "4;6;7;8", + "1;4;6;7;8", + "2;4;6;7;8", + "1;2;4;6;7;8", + "3;4;6;7;8", + "1;3;4;6;7;8", + "2;3;4;6;7;8", + "1;2;3;4;6;7;8", + "5;6;7;8", + "1;5;6;7;8", + "2;5;6;7;8", + "1;2;5;6;7;8", + "3;5;6;7;8", + "1;3;5;6;7;8", + "2;3;5;6;7;8", + "1;2;3;5;6;7;8", + "4;5;6;7;8", + "1;4;5;6;7;8", + "2;4;5;6;7;8", + "1;2;4;5;6;7;8", + "3;4;5;6;7;8", + "1;3;4;5;6;7;8", + "2;3;4;5;6;7;8", + "1;2;3;4;5;6;7;8", + "9", + "1;9", + "2;9", + "1;2;9", + "3;9", + "1;3;9", + "2;3;9", + "1;2;3;9", + "4;9", + "1;4;9", + "2;4;9", + "1;2;4;9", + "3;4;9", + "1;3;4;9", + "2;3;4;9", + "1;2;3;4;9", + "5;9", + "1;5;9", + "2;5;9", + "1;2;5;9", + "3;5;9", + "1;3;5;9", + "2;3;5;9", + "1;2;3;5;9", + "4;5;9", + "1;4;5;9", + "2;4;5;9", + "1;2;4;5;9", + "3;4;5;9", + "1;3;4;5;9", + "2;3;4;5;9", + "1;2;3;4;5;9", + "6;9", + "1;6;9", + "2;6;9", + "1;2;6;9", + "3;6;9", + "1;3;6;9", + "2;3;6;9", + "1;2;3;6;9", + "4;6;9", + "1;4;6;9", + "2;4;6;9", + "1;2;4;6;9", + "3;4;6;9", + "1;3;4;6;9", + "2;3;4;6;9", + "1;2;3;4;6;9", + "5;6;9", + "1;5;6;9", + "2;5;6;9", + "1;2;5;6;9", + "3;5;6;9", + "1;3;5;6;9", + "2;3;5;6;9", + "1;2;3;5;6;9", + "4;5;6;9", + "1;4;5;6;9", + "2;4;5;6;9", + "1;2;4;5;6;9", + "3;4;5;6;9", + "1;3;4;5;6;9", + "2;3;4;5;6;9", + "1;2;3;4;5;6;9", + "7;9", + "1;7;9", + "2;7;9", + "1;2;7;9", + "3;7;9", + "1;3;7;9", + "2;3;7;9", + "1;2;3;7;9", + "4;7;9", + "1;4;7;9", + "2;4;7;9", + "1;2;4;7;9", + "3;4;7;9", + "1;3;4;7;9", + "2;3;4;7;9", + "1;2;3;4;7;9", + "5;7;9", + "1;5;7;9", + "2;5;7;9", + "1;2;5;7;9", + "3;5;7;9", + "1;3;5;7;9", + "2;3;5;7;9", + "1;2;3;5;7;9", + "4;5;7;9", + "1;4;5;7;9", + "2;4;5;7;9", + "1;2;4;5;7;9", + "3;4;5;7;9", + "1;3;4;5;7;9", + "2;3;4;5;7;9", + "1;2;3;4;5;7;9", + "6;7;9", + "1;6;7;9", + "2;6;7;9", + "1;2;6;7;9", + "3;6;7;9", + "1;3;6;7;9", + "2;3;6;7;9", + "1;2;3;6;7;9", + "4;6;7;9", + "1;4;6;7;9", + "2;4;6;7;9", + "1;2;4;6;7;9", + "3;4;6;7;9", + "1;3;4;6;7;9", + "2;3;4;6;7;9", + "1;2;3;4;6;7;9", + "5;6;7;9", + "1;5;6;7;9", + "2;5;6;7;9", + "1;2;5;6;7;9", + "3;5;6;7;9", + "1;3;5;6;7;9", + "2;3;5;6;7;9", + "1;2;3;5;6;7;9", + "4;5;6;7;9", + "1;4;5;6;7;9", + "2;4;5;6;7;9", + "1;2;4;5;6;7;9", + "3;4;5;6;7;9", + "1;3;4;5;6;7;9", + "2;3;4;5;6;7;9", + "1;2;3;4;5;6;7;9", + "8;9", + "1;8;9", + "2;8;9", + "1;2;8;9", + "3;8;9", + "1;3;8;9", + "2;3;8;9", + "1;2;3;8;9", + "4;8;9", + "1;4;8;9", + "2;4;8;9", + "1;2;4;8;9", + "3;4;8;9", + "1;3;4;8;9", + "2;3;4;8;9", + "1;2;3;4;8;9", + "5;8;9", + "1;5;8;9", + "2;5;8;9", + "1;2;5;8;9", + "3;5;8;9", + "1;3;5;8;9", + "2;3;5;8;9", + "1;2;3;5;8;9", + "4;5;8;9", + "1;4;5;8;9", + "2;4;5;8;9", + "1;2;4;5;8;9", + "3;4;5;8;9", + "1;3;4;5;8;9", + "2;3;4;5;8;9", + "1;2;3;4;5;8;9", + "6;8;9", + "1;6;8;9", + "2;6;8;9", + "1;2;6;8;9", + "3;6;8;9", + "1;3;6;8;9", + "2;3;6;8;9", + "1;2;3;6;8;9", + "4;6;8;9", + "1;4;6;8;9", + "2;4;6;8;9", + "1;2;4;6;8;9", + "3;4;6;8;9", + "1;3;4;6;8;9", + "2;3;4;6;8;9", + "1;2;3;4;6;8;9", + "5;6;8;9", + "1;5;6;8;9", + "2;5;6;8;9", + "1;2;5;6;8;9", + "3;5;6;8;9", + "1;3;5;6;8;9", + "2;3;5;6;8;9", + "1;2;3;5;6;8;9", + "4;5;6;8;9", + "1;4;5;6;8;9", + "2;4;5;6;8;9", + "1;2;4;5;6;8;9", + "3;4;5;6;8;9", + "1;3;4;5;6;8;9", + "2;3;4;5;6;8;9", + "1;2;3;4;5;6;8;9", + "7;8;9", + "1;7;8;9", + "2;7;8;9", + "1;2;7;8;9", + "3;7;8;9", + "1;3;7;8;9", + "2;3;7;8;9", + "1;2;3;7;8;9", + "4;7;8;9", + "1;4;7;8;9", + "2;4;7;8;9", + "1;2;4;7;8;9", + "3;4;7;8;9", + "1;3;4;7;8;9", + "2;3;4;7;8;9", + "1;2;3;4;7;8;9", + "5;7;8;9", + "1;5;7;8;9", + "2;5;7;8;9", + "1;2;5;7;8;9", + "3;5;7;8;9", + "1;3;5;7;8;9", + "2;3;5;7;8;9", + "1;2;3;5;7;8;9", + "4;5;7;8;9", + "1;4;5;7;8;9", + "2;4;5;7;8;9", + "1;2;4;5;7;8;9", + "3;4;5;7;8;9", + "1;3;4;5;7;8;9", + "2;3;4;5;7;8;9", + "1;2;3;4;5;7;8;9", + "6;7;8;9", + "1;6;7;8;9", + "2;6;7;8;9", + "1;2;6;7;8;9", + "3;6;7;8;9", + "1;3;6;7;8;9", + "2;3;6;7;8;9", + "1;2;3;6;7;8;9", + "4;6;7;8;9", + "1;4;6;7;8;9", + "2;4;6;7;8;9", + "1;2;4;6;7;8;9", + "3;4;6;7;8;9", + "1;3;4;6;7;8;9", + "2;3;4;6;7;8;9", + "1;2;3;4;6;7;8;9", + "5;6;7;8;9", + "1;5;6;7;8;9", + "2;5;6;7;8;9", + "1;2;5;6;7;8;9", + "3;5;6;7;8;9", + "1;3;5;6;7;8;9", + "2;3;5;6;7;8;9", + "1;2;3;5;6;7;8;9", + "4;5;6;7;8;9", + "1;4;5;6;7;8;9", + "2;4;5;6;7;8;9", + "1;2;4;5;6;7;8;9", + "3;4;5;6;7;8;9", + "1;3;4;5;6;7;8;9", + "2;3;4;5;6;7;8;9", + "1;2;3;4;5;6;7;8;9", +] + diff --git a/rich/markdown.py b/rich/markdown.py index 273b0dbc..88bf70d5 100644 --- a/rich/markdown.py +++ b/rich/markdown.py @@ -476,27 +476,13 @@ An h2 header import commonmark - # print(commonmark.commonmark(markup)) - from .console import Console console = Console(record=True) - # print(console.size) - # markup = "" md = Markdown(markup) + from time import time + console.print(md) - print(console) - # print(console.render_spans()) - # from .color import Color - # from .style import Style - - # print(Color.downgrade.cache_info()) - # print(Color.parse.cache_info()) - # print(Color.get_ansi_codes.cache_info()) - - # Style.parse("on red") - - # print(Style.parse.cache_info()) diff --git a/rich/style.py b/rich/style.py index 5d929de6..fdf01f4b 100644 --- a/rich/style.py +++ b/rich/style.py @@ -4,6 +4,7 @@ from typing import Any, Dict, Iterable, List, Mapping, Optional, Type, Union from . import errors from .color import blend_rgb, Color, ColorParseError, ColorSystem +from ._style_table import STYLE_TABLE from .terminal_theme import TerminalTheme, DEFAULT_TERMINAL_THEME # Style instances and style definitions are often interchangable @@ -340,40 +341,14 @@ class Style: """ if color_system is None or not text: return text - attrs: List[str] = [] + _attributes = self._attributes & self._set_attributes + attrs: List[str] = [STYLE_TABLE[_attributes]] if _attributes else [] if self._color is not None: attrs.extend(self._color.downgrade(color_system).get_ansi_codes()) - if self._bgcolor is not None: attrs.extend( self._bgcolor.downgrade(color_system).get_ansi_codes(foreground=False) ) - - set_bits = self._set_attributes - if set_bits: - append = attrs.append - bits = self._attributes - if set_bits & 1: - append("1" if bits & 1 else "21") - if set_bits & 2: - append("2" if bits & 2 else "22") - if set_bits & 4: - append("3" if bits & 4 else "23") - if set_bits & 8: - append("4" if bits & 8 else "24") - # Early out for less common attributes - if set_bits & 0b111110000: - if set_bits & 16: - append("5" if bits & 16 else "25") - if set_bits & 32: - append("6" if bits & 32 else "26") - if set_bits & 64: - append("7" if bits & 64 else "27") - if set_bits & 128: - append("8" if bits & 128 else "28") - if set_bits & 256: - append("9" if bits & 256 else "29") - if attrs: return f"\x1b[{';'.join(attrs)}m{text or ''}\x1b[0m" else: diff --git a/tests/test_style.py b/tests/test_style.py index a2bbe746..6598c139 100644 --- a/tests/test_style.py +++ b/tests/test_style.py @@ -100,7 +100,7 @@ def test_render(): assert Style(color="red").render("foo", color_system=None) == "foo" assert ( Style(color="red", bgcolor="black", bold=True).render("foo") - == "\x1b[31;40;1mfoo\x1b[0m" + == "\x1b[1;31;40mfoo\x1b[0m" ) assert Style().render("foo") == "foo" diff --git a/tests/test_text.py b/tests/test_text.py index dcf032fa..b62c3ac0 100644 --- a/tests/test_text.py +++ b/tests/test_text.py @@ -282,6 +282,7 @@ def test_render(): ) console.print(test) output = console.export_text(styles=True) + print(repr(output)) expected = "\x1b[1;4mWhere\x1b[0m\x1b[4m there is \x1b[0m\n\x1b[4ma \x1b[0m\x1b[3;4mWill\x1b[0m\x1b[4m, there \x1b[0m\n\x1b[4mis a Way.\x1b[0m\n" assert output == expected