Skip to content

Commit

Permalink
feat!: change palette data structure to match json, add codegen (#29)
Browse files Browse the repository at this point in the history
Co-authored-by: Raffaele Mancuso <raffaele.mancuso4@unibo.it>
  • Loading branch information
backwardspy and raffaem committed Feb 17, 2024
1 parent 1759fd2 commit 8695144
Show file tree
Hide file tree
Showing 22 changed files with 3,138 additions and 543 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ on:
push:
paths:
- "**.py"
pull_request:
paths:
- "**.py"
jobs:
lint:
strategy:
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ on:
push:
paths:
- '**.py'
pull_request:
paths:
- "**.py"
jobs:
test:
strategy:
Expand Down
76 changes: 52 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,47 @@ pip install catppuccin

## Usage

Get access to the palette with the `catppuccin.PALETTE` constant:

```python
>>> from catppuccin import Flavour
>>> Flavour.latte().mauve.hex
'8839ef'
>>> Flavour.mocha().teal.rgb
(148, 226, 213)
from catppuccin import PALETTE

PALETTE.latte.colors.mauve.hex
# '#8839ef'
PALETTE.mocha.colors.teal.rgb
# RGB(r=148, g=226, b=213)
```

`Flavour` is a [`dataclass`](https://docs.python.org/3/library/dataclasses.html),
so you can inspect its fields to get access to the full set of colour names and values:
The `Palette` data structure matches [the palette JSON](https://github.com/catppuccin/palette/blob/main/palette.json).

### dataclasses

`Palette`, `Flavor`, `Color` et cetera are all [`dataclasses`](https://docs.python.org/3/library/dataclasses.html),
so you can also inspect and iterate their fields using methods from the dataclass module.

For example, to list all color names and their hex codes:

```python
>>> from dataclasses import fields
>>> flavour = Flavour.frappe()
>>> for field in fields(flavour):
colour = getattr(flavour, field.name)
print(f"{field.name}: #{colour.hex}")
rosewater: #f2d5cf
flamingo: #eebebe
pink: #f4b8e4
...
base: #303446
mantle: #292c3c
crust: #232634
from dataclasses import fields
from catppuccin import PALETTE

flavor = PALETTE.frappe
for field in fields(flavor.colors):
color = getattr(flavor.colors, field.name)
print(f"{field.name}: {color.hex}")

# rosewater: #f2d5cf
# flamingo: #eebebe
# pink: #f4b8e4
# ...
# base: #303446
# mantle: #292c3c
# crust: #232634
```

## Pygments Styles

This package provides a Pygments style for each of the four Catppuccin flavours.
This package provides a Pygments style for each of the four Catppuccin flavors.

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

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

```python
>>> from pygments.styles import get_style_by_name
>>> get_style_by_name("catppuccin-frappe")
catppuccin.extras.pygments.FrappeStyle
from pygments.styles import get_style_by_name

get_style_by_name("catppuccin-frappe")
# catppuccin.extras.pygments.FrappeStyle
```

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

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.
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 an example of a more complete configuration.

## Contribution

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

#### Codegen

[`catppuccin/palette.py`](./catppuccin/palette.py) is generated by a [build script](`./build.py`) based on the contents of [`palette.json`](./palette.json).

To update after downloading a new palette JSON file:

```console
poetry run python build.py
```

Formatting this file is done manually as with any other file, see [`Code Standards`](#code-standards) below.

#### Code Standards

Before committing changes, it is recommended to run the following tools to
Expand Down
65 changes: 65 additions & 0 deletions build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""Code generation script for creating the global palette constant."""
from __future__ import annotations

import json
from pathlib import Path
from typing import Any, cast

from catppuccin.models import HSL, RGB, Color, Flavor, FlavorColors, Palette

HEADER = '''"""Catppuccin palette definition."""
from catppuccin.models import HSL, RGB, Color, Flavor, FlavorColors, Palette'''


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(fields: dict[str, Any]) -> Color:
"""Create a Color instance from a set of fields."""
return Color(
name=fields["name"],
order=fields["order"],
hex=fields["hex"],
rgb=RGB(**fields["rgb"]),
hsl=HSL(**fields["hsl"]),
accent=fields["accent"],
)


def make_flavor(fields: dict[str, Any]) -> Flavor:
"""Create a Flavor instance from a set of fields."""
return Flavor(
name=fields["name"],
order=fields["order"],
dark=fields["dark"],
colors=FlavorColors(
**{
color_name: make_color(color_data)
for color_name, color_data in fields["colors"].items()
}
),
)


def codegen() -> str:
"""Generate contents of `catppuccin/palette.py`."""
palette_json = load_palette_json()
palette = Palette(
*[make_flavor(flavor_data) for flavor_data in palette_json.values()]
)

lines = [
HEADER,
f"PALETTE = {palette!r}",
]

return "\n".join(lines)


if __name__ == "__main__":
with Path("catppuccin/palette.py").open("w") as f:
source = codegen()
print(source, file=f)
7 changes: 4 additions & 3 deletions catppuccin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""🐍 Soothing pastel theme for Python."""
from catppuccin.colour import Colour
from catppuccin.flavour import Flavour

__all__ = ["Colour", "Flavour"]

from catppuccin.palette import PALETTE

__all__ = ["PALETTE"]
87 changes: 0 additions & 87 deletions catppuccin/colour.py

This file was deleted.

0 comments on commit 8695144

Please sign in to comment.