chroma icon indicating copy to clipboard operation
chroma copied to clipboard

Missing pygments styles

Open kovidgoyal opened this issue 2 years ago • 2 comments

Various builtin pygments styles are missing, for example default and stata. I can of course generate them for my own application using style.py, but I would rather avoid having to do so, since maintaining them in a central place is preferable.

kovidgoyal avatar Mar 21 '23 11:03 kovidgoyal

Here I attach a modified style.py that automatically dumps all builtin pygments styles as go sourcecode.

import importlib
import importlib.resources

import pystache
from pygments.style import Style
from pygments.token import Token


TEMPLATE = r'''
package styles

import (
    "github.com/alecthomas/chroma/v2"
)

// {{upper_name}} style.
var {{upper_name}} = Register(chroma.MustNewStyle("{{name}}", chroma.StyleEntries{
{{#styles}}
    chroma.{{type}}: "{{style}}",
{{/styles}}
}))
'''


def to_camel_case(snake_str):
    components = snake_str.split('_')
    return ''.join(x.title() for x in components)


def translate_token_type(t):
    if t == Token:
        t = Token.Background
    return "".join(map(str, t))


def convert_style(name, style_cls):
    styles = dict(style_cls.styles)
    bg = "bg:" + style_cls.background_color
    if Token in styles:
        styles[Token] += " " + bg
    else:
        styles[Token] = bg
    context = {
        'upper_name': style_cls.__name__[:-5],
        'name': name,
        'styles': [{'type': translate_token_type(t), 'style': s}
                   for t, s in styles.items() if s],
    }
    return pystache.render(TEMPLATE, context)


def all_builtin_style_module_names():
    for x in importlib.resources.contents('pygments.styles'):
        if '__' not in x and x.endswith('.py'):
            yield x[:-3]


def find_style_class_in_module(module_name):
    m = importlib.import_module('pygments.styles.' + module_name)
    for x in vars(m).values():
        if isinstance(x, type) and issubclass(x, Style) and x is not Style:
            return x
    raise ImportError(f'Failed to find Style sub-class in module: {module_name}')


def main():
    for module_name in all_builtin_style_module_names():
        text = convert_style(module_name, find_style_class_in_module(module_name))
        with open(f'{module_name}.go', 'w') as f:
            f.write(text)



if __name__ == '__main__':
    main()

kovidgoyal avatar Mar 21 '23 11:03 kovidgoyal

Thanks for the script. This made me realise that the style importer needs to be updated to output XML styles first.

alecthomas avatar Mar 23 '23 18:03 alecthomas