forked from catppuccin/python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.py
124 lines (96 loc) · 3.59 KB
/
build.py
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
"""Code generation script for creating the global palette constant."""
from __future__ import annotations
import json
import subprocess
from dataclasses import asdict
from pathlib import Path
from typing import Any, cast
from catppuccin.models import HSL, RGB, Color, Flavor, FlavorColors, Palette
from example_plots import example_plots, plot_palette
HEADER = '''"""Catppuccin palette definition."""
from catppuccin.models import HSL, RGB, Color, Flavor, FlavorColors, Palette'''
DPI = 200
def load_palette_json() -> dict[str, Any]:
"""Load palette data from `./palette.json`."""
with Path("palette.json").open() as f:
return cast(dict[str, Any], json.load(f))
def make_color(identifier: str, fields: dict[str, Any]) -> Color:
"""Create a Color instance from a set of fields."""
return Color(
name=fields["name"],
identifier=identifier,
accent=fields["accent"],
order=fields["order"],
hex=fields["hex"],
rgb=RGB(**fields["rgb"]),
hsl=HSL(**fields["hsl"]),
)
def make_flavor(identifier: str, fields: dict[str, Any]) -> Flavor:
"""Create a Flavor instance from a set of fields."""
return Flavor(
name=fields["name"],
identifier=identifier,
order=fields["order"],
dark=fields["dark"],
colors=FlavorColors(
**{
identifier: make_color(identifier, fields)
for identifier, fields in fields["colors"].items()
}
),
)
def codegen() -> str:
"""Generate contents of `catppuccin/palette.py`."""
palette_json = load_palette_json()
palette = Palette(
*[
make_flavor(identifier, fields)
for identifier, fields in palette_json.items()
]
)
lines = [
HEADER,
f"PALETTE = {palette!r}",
]
return "\n".join(lines)
if __name__ == "__main__":
# Generate the palette.py file
palette_path = Path.cwd() / "catppuccin" / "palette.py"
with palette_path.open("w") as f:
source = codegen()
print(source, file=f)
# Run `ruff format` on the generated file
ruff_format = f"ruff format {palette_path}"
subprocess.run(ruff_format.split(), check=True) # noqa: S603
# Generate the matplotlib styles
from catppuccin.extras.matplotlib import CATPPUCCIN_STYLE_DIRECTORY
from catppuccin.palette import PALETTE
template_text = (
CATPPUCCIN_STYLE_DIRECTORY / "_catppuccin_template.txt"
).read_text()
for key, palette in asdict(PALETTE).items():
text = template_text
text = text.replace("<palette>", key)
for color in palette["colors"]:
text = text.replace(
f"<{color}>",
palette["colors"][color]["hex"].replace("#", ""),
)
with (CATPPUCCIN_STYLE_DIRECTORY / f"{key}.mplstyle").open("w") as f:
f.write(text)
# Generate matplotlib assets for the docs
import matplotlib as mpl
import matplotlib.pyplot as plt
import catppuccin # This loads the styles in matplotlib # noqa: F401
for palette_name in asdict(PALETTE):
mpl.style.use(palette_name)
palette_path = Path.cwd() / "assets" / palette_name
palette_path.mkdir(exist_ok=True, parents=True)
# Plot palette separately
fig = plot_palette(palette_name)
fig.savefig(palette_path / "palette.png", dpi=DPI)
# Plot examples
for filename, plot_function in example_plots.items():
fig = plot_function()
fig.savefig(palette_path / f"{filename}.png", dpi=DPI)
plt.close()