aboutsummaryrefslogtreecommitdiff
path: root/kitty/kitty-themes/.tools/preview.py
blob: c29387ae62d443847e4e625ffecb168fb42539cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import sys
import os
import sys

theme_keys = [
    "cursor", "foreground", "background", "background_opacity", "dynamic_background_opacity", "dim_opacity",
    "selection_foreground", "selection_background", "color0", "color8", "color1", "color9", "color2", "color10",
    "color3", "color11", "color4", "color12", "color5", "color13", "color6", "color14", "color7", "color15"
]


def is_valid(line):
    """
    Returns true if a line inside a configuration file is a valid theme configuration pair: is not a comment, is not
    empty and the key is correct.

    :param line: a line inside the configuration file
    :type line: str
    :return: true if is valid, false otherwise
    :rtype: bool
    """
    return (not line.lstrip().startswith("#")  # is not a comment
            and len(line.strip()) != 0  # is not empty
            and line.split(maxsplit=1)[0] in theme_keys)  # key is a valid one


def extract_configuration_pair(line):
    """
    Extract a configuration pair by splitting on spaces and taking the first couple of values.

    :param line: a line inside the configuration file
    :type line: str
    :return: a key-value pair
    :rtype: bool
    """
    split = line.split(maxsplit=2)
    return split[0], split[1]


def read_configuration(filename):
    """
    Read a kitty configuration file and extract only theme related keys and values.

    :param filename: path to the configuration file
    :type filename: str
    :return: a map with theme related configuration values
    :rtype: dict[str, str]
    """
    with open(filename, "r") as fp:
        lines = fp.readlines()
        theme_config = dict([extract_configuration_pair(line) for line in lines if is_valid(line)])
    return theme_config


def fg(color, text):
    rgb = tuple(int(color[i + 1:i + 3], 16) for i in (0, 2, 4))
    return ('\x1b[38;2;%s;%s;%sm' % rgb + text + '\x1b[0m')


def bg(color, text):
    rgb = tuple(int(color[i + 1:i + 3], 16) for i in (0, 2, 4))
    return ('\x1b[48;2;%s;%s;%sm' % rgb + text + '\x1b[0m')


def print_preview(filename, configuration):
    cursor = configuration["cursor"]
    background = configuration["background"]
    foreground = configuration["foreground"]

    theme = os.path.basename(filename)

    size = len(theme) + (2 + 2 + 16 + 2 + 16 + 1 + 2)
    print(bg(background, " " * size))
    print(bg(background, "  "), end="")
    print(bg(background, fg(foreground, theme)), end="")
    print(bg(background, "  "), end="")

    c='a'
    for i in range(0, 16):
        color = configuration["color%d" % i]
        print(bg(background, fg(color, c)), end="")
        c = chr(ord(c) + 1)

    print(bg(background, "  "), end="")

    selection_background = configuration["selection_background"]
    selection_foreground = configuration["selection_foreground"]

    c='A'
    for i in range(0, 16):
        print(bg(selection_background, fg(selection_foreground, c)), end="")
        c = chr(ord(c) + 1)

    print(bg(cursor, " "), end="")
    print(bg(background, "  "))

    print(bg(background, " " * size))

    print(bg(background, "  "), end="")
    print(bg(configuration["color0"], " "), end="")
    print(bg(configuration["color1"], " "), end="")
    print(bg(configuration["color2"], " "), end="")
    print(bg(configuration["color3"], " "), end="")
    print(bg(configuration["color4"], " "), end="")
    print(bg(configuration["color5"], " "), end="")
    print(bg(configuration["color6"], " "), end="")
    print(bg(configuration["color7"], " "), end="")
    print(bg(background, "  "), end="")
    print(bg(configuration["color8"], " "), end="")
    print(bg(configuration["color9"], " "), end="")
    print(bg(configuration["color10"], " "), end="")
    print(bg(configuration["color11"], " "), end="")
    print(bg(configuration["color12"], " "), end="")
    print(bg(configuration["color13"], " "), end="")
    print(bg(configuration["color14"], " "), end="")
    print(bg(configuration["color15"], " "), end="")
    print(bg(background, " " * (size - 16 - 4)), end="")
    print()

    print(bg(background, " " * size))
    print()


def main(directory):
    for filename in os.listdir(directory):
        try:
            path = os.path.join(directory, filename)
            configuration = read_configuration(path)
            print_preview(path, configuration)
        except Exception as e:
            print(e, file=sys.stderr)
            print("Error while processing %s" % filename, file=sys.stderr)


if __name__ == "__main__":
    main(sys.argv[1])