aboutsummaryrefslogtreecommitdiff
path: root/src/theme.py
blob: fd1461af2a5bf29288c0ccdb3c6835f5f676b02c (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
import yaml,re, sys

def configure(theme):
    """
    Apply user define colors and apply some correction factors.
    """
    if "colors" in theme:
        colors=theme["colors"]
        window_colors=theme["window_colors"]

        ##### Apply colors to window #####
        for key1,value1 in window_colors.items():
            for key2,value2 in value1.items():
                if re.match("#.*",value2) == None:
                    window_colors[key1][key2]=colors[value2]
        theme["window_colors"]=window_colors
        ##################################
                
        ##### Apply color to bar #####
        bar_colors=theme["bar_colors"]
        for key1,value1 in bar_colors.items():
            if isinstance(value1,dict):
                for key2,value2 in value1.items():
                    if re.match("#.*",value2) == None:
                        bar_colors[key1][key2]=colors[value2]
            else:
                if re.match("#.*",value1) == None:
                    bar_colors[key1]=colors[value1]
        theme["bar_colors"]=bar_colors
        ##############################
        
    ##### I3-style theme do not include child_border by default #####
    window_colors=theme["window_colors"]
    for key,value in window_colors.items():
        if not("child_border" in value):
            newvalue=value
            theme["window_colors"][key]["child_border"]=newvalue["border"] # Set it to border by default
    #################################################################
    return(theme)

def validate(theme):
    """
    Abort if theme is in a wrong format.
    """
    abort=lambda msg: sys.exit("Error while loading theme: "+msg)
    inv_key=lambda key: abort("invalid key \""+key+"\"")
    for key,value in theme.items():
        if not(key in ["meta","colors","window_colors","bar_colors"]):
            inv_key(key)
        if key=="bar_colors":
            for key,value in value.items():
                if not(key in ["separator","background","statusline",
                               "focused_workspace","active_workspace","inactive_workspace","urgent_workspace"]):
                    inv_key(key)
        if key=="window_colors":
            for key,value in value.items():
                if not(key in ["focused","focused_inactive","unfocused","urgent","child_border"]):
                    inv_key(key)
                    
def load(theme_file):
    """
    Load a theme as a dict():
      - Open YAML file
      - Parse it as a dict
      - Configure the parsed dict
      - Validate the configured dict
    """
    f=open(theme_file,mode="r")
    theme=yaml.load(f,Loader=yaml.FullLoader)
    f.close()
    theme=configure(theme)
    validate(theme)
    return(theme)

class ThemeBuilder:
    def __init__(self):
        self.theme={"meta": {"description": "Generated From i3-colors"},
                        "window_colors":dict(),
                        "bar_colors":dict()}
    def dump(self):
        print(yaml.dump(self.theme))

    def parse(self,line):
        if re.match("client.*",line):
            tokens=line.split()
            key=tokens[0].replace("client.","")
            tokens.pop(0)
            subkeys=["border","background","text","indicator","child_border"]
            self.theme["window_colors"][key]=dict()
            for token in tokens:
                self.theme["window_colors"][key][subkeys[0]]=token
                subkeys.pop(0)
        elif re.match(".*background.*",line):
            self.theme["bar_colors"]["background"]=line.split()[1]
        elif re.match(".*statusline.*",line):
            self.theme["bar_colors"]["statusline"]=line.split()[1]
        elif re.match(".*separator.*",line):
            self.theme["bar_colors"]["separator"]=line.split()[1]
        elif re.match(".*_workspace.*",line):
            tokens=line.split()
            key=tokens[0]
            tokens.pop(0)
            subkeys=["border","background","text"]
            self.theme["bar_colors"][key]=dict()
            for token in tokens:
                self.theme["bar_colors"][key][subkeys[0]]=token
                subkeys.pop(0)