summaryrefslogtreecommitdiff
path: root/pywal/export.py
blob: d9ff16dcefecadb88222e435d89c58b1f6866d50 (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
"""
Export colors in various formats.
"""
import logging
import os
import re

from . import util
from .settings import CACHE_DIR, CONF_DIR, MODULE_DIR


def template(colors, input_file, output_file=None):
    """Read template file, substitute markers and
       save the file elsewhere."""
    template_data = util.read_file_raw(input_file)
    for i, l in enumerate(template_data):
        for match in re.finditer(r"(?<=(?<!\{))(\{([^{}]+)\})(?=(?!\}))", l):
            # Get the color, and the functions associated with it
            cname, _, funcs = match.group(2).partition(".")
            # Check that functions are needed for this color
            if len(funcs) == 0:
                continue
            # Build up a string which will be replaced with the new color
            replace_str = cname
            # Color to be modified copied into new one
            new_color = util.Color(colors[cname].hex_color)
            # Execute each function to be done
            for func in filter(None, funcs.split(")")):
                # Get function name and arguments
                func = func.split("(")
                fname = func[0]
                if fname[0] == '.':
                    fname = fname[1:]
                if not hasattr(new_color, fname):
                    logging.error(
                        "Syntax error in template file '%s' on line '%s'",
                        input_file, i)
                function = getattr(new_color, fname)

                # If the function is callable, call it
                if callable(function):
                    if len(func) > 1:
                        new_color = function(*func[1].split(","))
                    else:
                        new_color = function()
                    # string to replace generated colors
                    if func[0] != '.':
                        replace_str += "."
                    replace_str += "(".join(func) + ")"
            # If the color was changed, replace with a unique identifier.
            if new_color is not colors[cname]:
                template_data[i] = l.replace(
                    replace_str, "color" + new_color.strip)
                colors["color" + new_color.strip] = new_color
    try:
        template_data = "".join(template_data).format(**colors)
    except ValueError:
        logging.error("Syntax error in template file '%s'.", input_file)
        return
    util.save_file(template_data, output_file)


def flatten_colors(colors):
    """Prepare colors to be exported.
       Flatten dicts and convert colors to util.Color()"""
    all_colors = {"wallpaper": colors["wallpaper"],
                  "alpha": colors["alpha"],
                  **colors["special"],
                  **colors["colors"]}
    return {k: util.Color(v) for k, v in all_colors.items()}


def get_export_type(export_type):
    """Convert template type to the right filename."""
    return {
        "css": "colors.css",
        "dmenu": "colors-wal-dmenu.h",
        "dwm": "colors-wal-dwm.h",
        "st": "colors-wal-st.h",
        "tabbed": "colors-wal-tabbed.h",
        "gtk2": "colors-gtk2.rc",
        "json": "colors.json",
        "konsole": "colors-konsole.colorscheme",
        "kitty": "colors-kitty.conf",
        "plain": "colors",
        "putty": "colors-putty.reg",
        "rofi": "colors-rofi.Xresources",
        "scss": "colors.scss",
        "shell": "colors.sh",
        "speedcrunch": "colors-speedcrunch.json",
        "sway": "colors-sway",
        "tty": "colors-tty.sh",
        "waybar": "colors-waybar.css",
        "xresources": "colors.Xresources",
        "xmonad": "colors.hs",
        "yaml": "colors.yml",
    }.get(export_type, export_type)


def every(colors, output_dir=CACHE_DIR):
    """Export all template files."""
    colors = flatten_colors(colors)
    template_dir = os.path.join(MODULE_DIR, "templates")
    template_dir_user = os.path.join(CONF_DIR, "templates")
    util.create_dir(template_dir_user)

    join = os.path.join  # Minor optimization.
    for file in [*os.scandir(template_dir),
                 *os.scandir(template_dir_user)]:
        if file.name != ".DS_Store" and not file.name.endswith(".swp"):
            template(colors, file.path, join(output_dir, file.name))

    logging.info("Exported all files.")
    logging.info("Exported all user files.")


def color(colors, export_type, output_file=None):
    """Export a single template file."""
    all_colors = flatten_colors(colors)

    template_name = get_export_type(export_type)
    template_file = os.path.join(MODULE_DIR, "templates", template_name)
    output_file = output_file or os.path.join(CACHE_DIR, template_name)

    if os.path.isfile(template_file):
        template(all_colors, template_file, output_file)
        logging.info("Exported %s.", export_type)
    else:
        logging.warning("Template '%s' doesn't exist.", export_type)