diff --git a/README.md b/README.md index ec27e16..8ed79a7 100644 --- a/README.md +++ b/README.md @@ -73,9 +73,9 @@ ensure consistency in the codebase. ```bash isort . black . -pylint catppuccin.py +pylint catppuccin mypy . -pytest --cov +pytest --cov catppuccin ``` These tools are all installed as part of the `dev` dependency group with diff --git a/catppuccin/__init__.py b/catppuccin/__init__.py new file mode 100644 index 0000000..92b42b8 --- /dev/null +++ b/catppuccin/__init__.py @@ -0,0 +1,3 @@ +"""🐍 Soothing pastel theme for Python.""" +from catppuccin.colour import Colour as Colour +from catppuccin.flavour import Flavour as Flavour diff --git a/catppuccin/colour.py b/catppuccin/colour.py new file mode 100644 index 0000000..00ac59d --- /dev/null +++ b/catppuccin/colour.py @@ -0,0 +1,24 @@ +""" +Functionality relating to individual colours. +""" +from dataclasses import dataclass +from typing import Tuple + + +@dataclass(frozen=True) +class Colour: + """A colour with three channels; red, green, and blue.""" + + red: int + green: int + blue: int + + @property + def rgb(self) -> Tuple[int, int, int]: + """Get the colour as a 3-tuple of red, green, and blue.""" + return (self.red, self.green, self.blue) + + @property + def hex(self) -> str: + """Get the colour as a lowercase hex string.""" + return f"{self.red:02x}{self.green:02x}{self.blue:02x}" diff --git a/catppuccin/extras/__init__.py b/catppuccin/extras/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/catppuccin/extras/pygments.py b/catppuccin/extras/pygments.py new file mode 100644 index 0000000..ebdcd18 --- /dev/null +++ b/catppuccin/extras/pygments.py @@ -0,0 +1,73 @@ +""" +Pygments styles for all Catppuccin flavours. +""" +from pygments.style import Style +from pygments.token import ( + Comment, + Error, + Keyword, + Literal, + Name, + Number, + Operator, + Punctuation, + String, + Text, + Token, + _TokenType, +) + +from catppuccin.flavour import Flavour + + +def _make_styles(flavour: Flavour) -> dict[_TokenType, str]: + return { + Token: f"#{flavour.text.hex}", + Text: f"#{flavour.text.hex}", + Error: f"#{flavour.red.hex}", + Keyword: f"#{flavour.mauve.hex}", + Keyword.Constant: f"#{flavour.peach.hex}", + Keyword.Declaration: f"#{flavour.blue.hex}", + Keyword.Namespace: f"#{flavour.teal.hex}", + Keyword.Pseudo: f"#{flavour.mauve.hex}", + Keyword.Reserved: f"#{flavour.mauve.hex}", + Keyword.Type: f"#{flavour.blue.hex}", + Name: f"#{flavour.peach.hex}", + Name.Attribute: f"#{flavour.blue.hex}", + Name.Constant: f"#{flavour.yellow.hex}", + Name.Decorator: f"#{flavour.blue.hex}", + Name.Function: f"#{flavour.blue.hex}", + Name.Function.Magic: f"#{flavour.sky.hex}", + Name.Label: f"#{flavour.blue.hex}", + Name.Tag: f"#{flavour.mauve.hex}", + Literal: f"#{flavour.text.hex}", + String: f"#{flavour.green.hex}", + Number: f"#{flavour.peach.hex}", + Punctuation: f"#{flavour.text.hex}", + Operator: f"#{flavour.sky.hex}", + Comment: f"#{flavour.overlay0.hex}", + } + + +class LatteStyle(Style): # pylint: disable=too-few-public-methods + """Catppuccin Latte pygments style.""" + + styles = _make_styles(Flavour.latte()) + + +class FrappeStyle(Style): # pylint: disable=too-few-public-methods + """Catppuccin Frappé pygments style.""" + + styles = _make_styles(Flavour.frappe()) + + +class MacchiatoStyle(Style): # pylint: disable=too-few-public-methods + """Catppuccin Macchiato pygments style.""" + + styles = _make_styles(Flavour.macchiato()) + + +class MochaStyle(Style): # pylint: disable=too-few-public-methods + """Catppuccin Mocha pygments style.""" + + styles = _make_styles(Flavour.mocha()) diff --git a/catppuccin.py b/catppuccin/flavour.py similarity index 90% rename from catppuccin.py rename to catppuccin/flavour.py index e8b9fb8..aa7df98 100644 --- a/catppuccin.py +++ b/catppuccin/flavour.py @@ -1,25 +1,10 @@ -"""🐍 Soothing pastel theme for Python.""" +""" +Functionality relating to Catppuccin flavours. +A flavour is a collection of colours. +""" from dataclasses import dataclass -from typing import Tuple - -@dataclass(frozen=True) -class Colour: - """A colour with three channels; red, green, and blue.""" - - red: int - green: int - blue: int - - @property - def rgb(self) -> Tuple[int, int, int]: - """Get the colour as a 3-tuple of red, green, and blue.""" - return (self.red, self.green, self.blue) - - @property - def hex(self) -> str: - """Get the colour as a lowercase hex string.""" - return f"{self.red:02x}{self.green:02x}{self.blue:02x}" +from catppuccin.colour import Colour @dataclass(frozen=True) diff --git a/poetry.lock b/poetry.lock index 63b04a0..f65da2d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -236,6 +236,17 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "pygments" +version = "2.13.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "main" +optional = true +python-versions = ">=3.6" + +[package.extras] +plugins = ["importlib-metadata"] + [[package]] name = "pylint" version = "2.15.5" @@ -330,6 +341,34 @@ category = "dev" optional = false python-versions = ">=3.6" +[[package]] +name = "types-docutils" +version = "0.19.1.1" +description = "Typing stubs for docutils" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "types-pygments" +version = "2.13.1.1" +description = "Typing stubs for Pygments" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +types-docutils = "*" +types-setuptools = "*" + +[[package]] +name = "types-setuptools" +version = "65.5.0.3" +description = "Typing stubs for setuptools" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "typing-extensions" version = "4.4.0" @@ -358,10 +397,13 @@ python-versions = ">=3.7" docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +[extras] +pygments = ["pygments"] + [metadata] lock-version = "1.1" python-versions = "^3.7.2" -content-hash = "2d85a7c457c2793692572a27a7888bf3b7d8bab70651633749886dd13e4124af" +content-hash = "8b674e8b255aff8f4a660429b32906486cdf6a099268217aa83ad468d0596d43" [metadata.files] astroid = [ @@ -546,6 +588,10 @@ pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] +pygments = [ + {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, + {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, +] pylint = [ {file = "pylint-2.15.5-py3-none-any.whl", hash = "sha256:c2108037eb074334d9e874dc3c783752cc03d0796c88c9a9af282d0f161a1004"}, {file = "pylint-2.15.5.tar.gz", hash = "sha256:3b120505e5af1d06a5ad76b55d8660d44bf0f2fc3c59c2bdd94e39188ee3a4df"}, @@ -596,6 +642,18 @@ typed-ast = [ {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, ] +types-docutils = [ + {file = "types-docutils-0.19.1.1.tar.gz", hash = "sha256:be0a51ba1c7dd215d9d2df66d6845e63c1009b4bbf4c5beb87a0d9745cdba962"}, + {file = "types_docutils-0.19.1.1-py3-none-any.whl", hash = "sha256:a024cada35f0c13cc45eb0b68a102719018a634013690b7fef723bcbfadbd1f1"}, +] +types-pygments = [ + {file = "types-Pygments-2.13.1.1.tar.gz", hash = "sha256:bcc24601e698b1393744f77901376d55b7a9a6a23d4f4ba80c84347c1f7939b1"}, + {file = "types_Pygments-2.13.1.1-py3-none-any.whl", hash = "sha256:9c789be357e21f611d215af3ae9dfcc24469dc4be96e96ea9b4e5e0c783afba5"}, +] +types-setuptools = [ + {file = "types-setuptools-65.5.0.3.tar.gz", hash = "sha256:17769171f5f2a2dc69b25c0d3106552a5cda767bbf6b36cb6212b26dae5aa9fc"}, + {file = "types_setuptools-65.5.0.3-py3-none-any.whl", hash = "sha256:9254c32b0cc91c486548e7d7561243b5bd185402a383e93c6691e1b9bc8d86e2"}, +] typing-extensions = [ {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, diff --git a/pyproject.toml b/pyproject.toml index 2a37121..a79f611 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,6 +11,10 @@ readme = "README.md" [tool.poetry.dependencies] python = "^3.7.2" +pygments = { version = "^2.13.0", optional = true } + +[tool.poetry.extras] +pygments = ["pygments"] [tool.poetry.group.dev.dependencies] pylint = "^2.15.5" @@ -19,6 +23,13 @@ black = "^22.10.0" isort = "^5.10.1" pytest = "^7.2.0" pytest-cov = "^4.0.0" +types-setuptools = "^65.5.0.3" +types-pygments = "^2.13.1.1" -[too.isort] +[tool.pylint.messages_control] +disable = [ + "useless-import-alias", # pyright compatibility +] + +[tool.isort] profile = "black" diff --git a/tests/test_colour.py b/tests/test_colour.py index ddfa194..c1e3731 100644 --- a/tests/test_colour.py +++ b/tests/test_colour.py @@ -1,4 +1,4 @@ -from catppuccin import Colour +from catppuccin.colour import Colour def test_colour_to_rgb(): diff --git a/tests/test_flavour.py b/tests/test_flavour.py index ad5b30b..fe50cb4 100644 --- a/tests/test_flavour.py +++ b/tests/test_flavour.py @@ -1,8 +1,7 @@ from typing import cast -from catppuccin import Flavour - -from .conftest import ColourJSON, FlavourJSON, PaletteJSON +from catppuccin.flavour import Flavour +from tests.conftest import ColourJSON, FlavourJSON, PaletteJSON def validate_flavour(flavour: Flavour, flavour_json: FlavourJSON) -> None: