From d5252575601c6c96896baca1fa170ab0f02b4f3f Mon Sep 17 00:00:00 2001 From: jrijul1201 Date: Tue, 19 Dec 2023 13:27:49 +0530 Subject: [PATCH] config/themes: Convert pygments styles to urwid compatible styles. Pygments 2.16.0 introduced a style to support a combination of bold and italic styling in pygments/pygments#2444. Both of our gruvbox themes and the light native theme gain a 'bold strong' style via pygments as a result, which urwid fails to parse and blocks the application from loading. This work would represent a clean fix for #1431, which was temporarily fixed by pinning pygments at ~=2.15.1 in #1433. Add method `translate_styles` that manually converts the pygments `bold italic` style into the urwid-compatible `bold, italics`. Tests added. Fixes part of #1434. --- tests/config/test_themes.py | 64 +++++++++++++++++++++++++++++++++- zulipterminal/config/themes.py | 24 ++++++++++++- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/tests/config/test_themes.py b/tests/config/test_themes.py index b06e35df39..aa77d878fe 100644 --- a/tests/config/test_themes.py +++ b/tests/config/test_themes.py @@ -5,13 +5,14 @@ import pytest from pygments.styles.material import MaterialStyle from pygments.styles.perldoc import PerldocStyle -from pygments.token import STANDARD_TYPES +from pygments.token import STANDARD_TYPES, _TokenType from pytest import param as case from pytest_mock import MockerFixture from zulipterminal.config.regexes import REGEX_COLOR_VALID_FORMATS from zulipterminal.config.themes import ( REQUIRED_STYLES, + STYLE_TRANSLATIONS, THEMES, InvalidThemeColorCode, MissingThemeAttributeError, @@ -20,6 +21,7 @@ complete_and_incomplete_themes, generate_pygments_styles, generate_theme, + generate_urwid_compatible_pygments_styles, parse_themefile, valid_16_color_codes, validate_colors, @@ -402,3 +404,63 @@ class Color3(Enum): + "- GRAY_244 = dark_gra\n" + "- LIGHT2 = whit" ) + + +@pytest.mark.parametrize( + "pygments_styles, expected_styles, style_translations", + [ + case( + {}, + {}, + STYLE_TRANSLATIONS, + id="empty_input", + ), + case( + { + "token1": "style1", + "token2": "style2", + }, + { + "token1": "style1", + "token2": "style2", + }, + {}, + id="empty_translations", + ), + case( + { + "token1": "bold italic", + "token2": "italic bold", + "token3": "italic #abc", + }, + { + "token1": "bold,italics", + "token2": "italics,bold", + "token3": "italics,#abc", + }, + STYLE_TRANSLATIONS, + id="default_translations", + ), + case( + { + "token1": "style italic", + "token2": "#abc", + }, + { + "token1": "newstyle italic", + "token2": "#abc", + }, + {"style": "newstyle"}, + id="custom_translations", + ), + ], +) +def test_generate_urwid_compatible_pygments_styles( + pygments_styles: Dict[_TokenType, str], + expected_styles: Dict[_TokenType, str], + style_translations: Dict[str, str], +) -> None: + generated_styles = generate_urwid_compatible_pygments_styles( + pygments_styles, style_translations + ) + assert sorted(expected_styles.items()) == sorted(generated_styles.items()) diff --git a/zulipterminal/config/themes.py b/zulipterminal/config/themes.py index c9e5174a40..7c6dfe56da 100644 --- a/zulipterminal/config/themes.py +++ b/zulipterminal/config/themes.py @@ -3,7 +3,7 @@ """ from typing import Any, Dict, List, Optional, Tuple, Union -from pygments.token import STANDARD_TYPES +from pygments.token import STANDARD_TYPES, _TokenType from zulipterminal.config.color import term16 from zulipterminal.themes import gruvbox_dark, gruvbox_light, zt_blue, zt_dark, zt_light @@ -128,6 +128,13 @@ "white", ] +# These are style_translations for translating pygments styles into +# urwid-compatible styles +STYLE_TRANSLATIONS = { + " ": ",", + "italic": "italics", +} + class ThemeError(Exception): pass @@ -255,6 +262,19 @@ def parse_themefile( return urwid_theme +def generate_urwid_compatible_pygments_styles( + pygments_styles: Dict[_TokenType, str], + style_translations: Dict[str, str] = STYLE_TRANSLATIONS, +) -> Dict[_TokenType, str]: + urwid_compatible_styles = {} + for token, style in pygments_styles.items(): + updated_style = style + for old_value, new_value in style_translations.items(): + updated_style = updated_style.replace(old_value, new_value) + urwid_compatible_styles[token] = updated_style + return urwid_compatible_styles + + def generate_pygments_styles(pygments: Dict[str, Any]) -> ThemeSpec: """ This function adds pygments styles for use in syntax @@ -278,6 +298,8 @@ def generate_pygments_styles(pygments: Dict[str, Any]) -> ThemeSpec: term16_bg = term16.background_color theme_styles_from_pygments: ThemeSpec = [] + pygments_styles = generate_urwid_compatible_pygments_styles(pygments_styles) + for token, css_class in STANDARD_TYPES.items(): if css_class in pygments_overrides: pygments_styles[token] = pygments_overrides[css_class]