Skip to content

Commit 8695144

Browse files
backwardspyraffaem
andauthored
feat!: change palette data structure to match json, add codegen (#29)
Co-authored-by: Raffaele Mancuso <[email protected]>
1 parent 1759fd2 commit 8695144

22 files changed

+3138
-543
lines changed

.github/workflows/lint.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ on:
33
push:
44
paths:
55
- "**.py"
6-
pull_request:
7-
paths:
8-
- "**.py"
96
jobs:
107
lint:
118
strategy:

.github/workflows/test.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ on:
33
push:
44
paths:
55
- '**.py'
6-
pull_request:
7-
paths:
8-
- "**.py"
96
jobs:
107
test:
118
strategy:

README.md

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,47 @@ pip install catppuccin
2121

2222
## Usage
2323

24+
Get access to the palette with the `catppuccin.PALETTE` constant:
25+
2426
```python
25-
>>> from catppuccin import Flavour
26-
>>> Flavour.latte().mauve.hex
27-
'8839ef'
28-
>>> Flavour.mocha().teal.rgb
29-
(148, 226, 213)
27+
from catppuccin import PALETTE
28+
29+
PALETTE.latte.colors.mauve.hex
30+
# '#8839ef'
31+
PALETTE.mocha.colors.teal.rgb
32+
# RGB(r=148, g=226, b=213)
3033
```
3134

32-
`Flavour` is a [`dataclass`](https://docs.python.org/3/library/dataclasses.html),
33-
so you can inspect its fields to get access to the full set of colour names and values:
35+
The `Palette` data structure matches [the palette JSON](https://github.com/catppuccin/palette/blob/main/palette.json).
36+
37+
### dataclasses
38+
39+
`Palette`, `Flavor`, `Color` et cetera are all [`dataclasses`](https://docs.python.org/3/library/dataclasses.html),
40+
so you can also inspect and iterate their fields using methods from the dataclass module.
41+
42+
For example, to list all color names and their hex codes:
3443

3544
```python
36-
>>> from dataclasses import fields
37-
>>> flavour = Flavour.frappe()
38-
>>> for field in fields(flavour):
39-
colour = getattr(flavour, field.name)
40-
print(f"{field.name}: #{colour.hex}")
41-
rosewater: #f2d5cf
42-
flamingo: #eebebe
43-
pink: #f4b8e4
44-
...
45-
base: #303446
46-
mantle: #292c3c
47-
crust: #232634
45+
from dataclasses import fields
46+
from catppuccin import PALETTE
47+
48+
flavor = PALETTE.frappe
49+
for field in fields(flavor.colors):
50+
color = getattr(flavor.colors, field.name)
51+
print(f"{field.name}: {color.hex}")
52+
53+
# rosewater: #f2d5cf
54+
# flamingo: #eebebe
55+
# pink: #f4b8e4
56+
# ...
57+
# base: #303446
58+
# mantle: #292c3c
59+
# crust: #232634
4860
```
4961

5062
## Pygments Styles
5163

52-
This package provides a Pygments style for each of the four Catppuccin flavours.
64+
This package provides a Pygments style for each of the four Catppuccin flavors.
5365

5466
Install Catppuccin with the `pygments` feature to include the relevant dependencies:
5567

@@ -61,9 +73,10 @@ The styles are registered as importlib entrypoints, which allows Pygments to
6173
find them by name:
6274

6375
```python
64-
>>> from pygments.styles import get_style_by_name
65-
>>> get_style_by_name("catppuccin-frappe")
66-
catppuccin.extras.pygments.FrappeStyle
76+
from pygments.styles import get_style_by_name
77+
78+
get_style_by_name("catppuccin-frappe")
79+
# catppuccin.extras.pygments.FrappeStyle
6780
```
6881

6982
The following style names are available:
@@ -88,7 +101,10 @@ c.TerminalInteractiveShell.true_color = True
88101
c.TerminalInteractiveShell.highlighting_style = "catppuccin-mocha"
89102
```
90103

91-
Putting this into your [IPython configuration](https://ipython.readthedocs.io/en/stable/config/intro.html) and ensuring `catppuccin[pygments]` is installed in the same environment will give you Catppuccin Mocha syntax highlighting in the REPL. See [here](https://github.com/backwardspy/dots/blob/f6991570d6691212e27e266517656192f910ccbf/dot_config/ipython/profile_default/ipython_config.py) for a more complete example configuration.
104+
Putting this into your [IPython configuration](https://ipython.readthedocs.io/en/stable/config/intro.html)
105+
and ensuring `catppuccin[pygments]` is installed in the same environment will
106+
give you Catppuccin Mocha syntax highlighting in the REPL. See [here](https://github.com/backwardspy/dots/blob/f6991570d6691212e27e266517656192f910ccbf/dot_config/ipython/profile_default/ipython_config.py)
107+
for an example of a more complete configuration.
92108

93109
## Contribution
94110

@@ -108,6 +124,18 @@ Install the project's dependencies including extras:
108124
poetry install --all-extras
109125
```
110126

127+
#### Codegen
128+
129+
[`catppuccin/palette.py`](./catppuccin/palette.py) is generated by a [build script](`./build.py`) based on the contents of [`palette.json`](./palette.json).
130+
131+
To update after downloading a new palette JSON file:
132+
133+
```console
134+
poetry run python build.py
135+
```
136+
137+
Formatting this file is done manually as with any other file, see [`Code Standards`](#code-standards) below.
138+
111139
#### Code Standards
112140

113141
Before committing changes, it is recommended to run the following tools to

build.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""Code generation script for creating the global palette constant."""
2+
from __future__ import annotations
3+
4+
import json
5+
from pathlib import Path
6+
from typing import Any, cast
7+
8+
from catppuccin.models import HSL, RGB, Color, Flavor, FlavorColors, Palette
9+
10+
HEADER = '''"""Catppuccin palette definition."""
11+
from catppuccin.models import HSL, RGB, Color, Flavor, FlavorColors, Palette'''
12+
13+
14+
def load_palette_json() -> dict[str, Any]:
15+
"""Load palette data from `./palette.json`."""
16+
with Path("palette.json").open() as f:
17+
return cast(dict[str, Any], json.load(f))
18+
19+
20+
def make_color(fields: dict[str, Any]) -> Color:
21+
"""Create a Color instance from a set of fields."""
22+
return Color(
23+
name=fields["name"],
24+
order=fields["order"],
25+
hex=fields["hex"],
26+
rgb=RGB(**fields["rgb"]),
27+
hsl=HSL(**fields["hsl"]),
28+
accent=fields["accent"],
29+
)
30+
31+
32+
def make_flavor(fields: dict[str, Any]) -> Flavor:
33+
"""Create a Flavor instance from a set of fields."""
34+
return Flavor(
35+
name=fields["name"],
36+
order=fields["order"],
37+
dark=fields["dark"],
38+
colors=FlavorColors(
39+
**{
40+
color_name: make_color(color_data)
41+
for color_name, color_data in fields["colors"].items()
42+
}
43+
),
44+
)
45+
46+
47+
def codegen() -> str:
48+
"""Generate contents of `catppuccin/palette.py`."""
49+
palette_json = load_palette_json()
50+
palette = Palette(
51+
*[make_flavor(flavor_data) for flavor_data in palette_json.values()]
52+
)
53+
54+
lines = [
55+
HEADER,
56+
f"PALETTE = {palette!r}",
57+
]
58+
59+
return "\n".join(lines)
60+
61+
62+
if __name__ == "__main__":
63+
with Path("catppuccin/palette.py").open("w") as f:
64+
source = codegen()
65+
print(source, file=f)

catppuccin/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""🐍 Soothing pastel theme for Python."""
2-
from catppuccin.colour import Colour
3-
from catppuccin.flavour import Flavour
42

5-
__all__ = ["Colour", "Flavour"]
3+
4+
from catppuccin.palette import PALETTE
5+
6+
__all__ = ["PALETTE"]

catppuccin/colour.py

Lines changed: 0 additions & 87 deletions
This file was deleted.

0 commit comments

Comments
 (0)