Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4ee9e23c5c | |||
| a5256aaa62 | |||
| 99ed1c9557 | |||
| 356442395e | |||
| fcaa25e2f5 | |||
| 4a5f8cbb39 | |||
| eb02be9582 | |||
| 74c22552df |
2
.gitignore
vendored
@@ -23,3 +23,5 @@ archive/
|
|||||||
notebooks/color_spaces_manyview.ipynb
|
notebooks/color_spaces_manyview.ipynb
|
||||||
notebooks/oklch_srgb_spherical.ipynb
|
notebooks/oklch_srgb_spherical.ipynb
|
||||||
notebooks/v1.4.0/
|
notebooks/v1.4.0/
|
||||||
|
notebooks/v1.5.1/
|
||||||
|
CHECKLIST.md
|
||||||
|
|||||||
55
README.md
@@ -31,12 +31,12 @@ Monotone curves have fixed chroma, whereas the accent curves' chroma varies
|
|||||||
smoothly as a function of lightness within sRGB gamut bounds.
|
smoothly as a function of lightness within sRGB gamut bounds.
|
||||||
|
|
||||||
| Chroma curves | Color trajectories |
|
| Chroma curves | Color trajectories |
|
||||||
|---|---|
|
|----------------------------------------------------------|------------------------------------------|
|
||||||
|  |  |
|
|  |  |
|
||||||
|
|
||||||
| Palette |
|
| Palette |
|
||||||
|---|
|
|----------------------------------------------|
|
||||||
|  |
|
|  |
|
||||||
|
|
||||||
Chroma curves are designed specifically to establish a distinct role for each
|
Chroma curves are designed specifically to establish a distinct role for each
|
||||||
accent and are non-intersecting over the lightness domain (hence the distinct
|
accent and are non-intersecting over the lightness domain (hence the distinct
|
||||||
@@ -61,7 +61,7 @@ varying only in lightness from dark to light grey.
|
|||||||
## Themes
|
## Themes
|
||||||
|
|
||||||
| Dark themes | Light themes |
|
| Dark themes | Light themes |
|
||||||
|---|---|
|
|----------------------------------------|------------------------------------------|
|
||||||
|  |  |
|
|  |  |
|
||||||
|
|
||||||
Themes are derived from the `monobiome` palette by selecting a monotone base
|
Themes are derived from the `monobiome` palette by selecting a monotone base
|
||||||
@@ -79,7 +79,7 @@ The following plots show the intersection of the sphere centered at a fixed
|
|||||||
background color (`alpine` biome with a lightness of 20) under variable radii:
|
background color (`alpine` biome with a lightness of 20) under variable radii:
|
||||||
|
|
||||||
| | `-l 20 -d 0.3` | `-l 20 -d 0.4` | `-l 20 -d 0.5` |
|
| | `-l 20 -d 0.3` | `-l 20 -d 0.4` | `-l 20 -d 0.5` |
|
||||||
|---|---|---|---|
|
|---------------------|---------------------------------------------------|---------------------------------------------------|---------------------------------------------------|
|
||||||
| Color visualization |  |  |  |
|
| Color visualization |  |  |  |
|
||||||
| Editor preview |  |  |  |
|
| Editor preview |  |  |  |
|
||||||
|
|
||||||
@@ -117,10 +117,10 @@ theme pipeline can be seen in detail below:
|
|||||||

|

|
||||||
|
|
||||||
This figure demonstrates how `kitty` themes are generated, but the process is
|
This figure demonstrates how `kitty` themes are generated, but the process is
|
||||||
generic to any palette, scheme, and app. This implemented in two stages using
|
generic to any palette, scheme, and app. This is implemented in two stages
|
||||||
the `monobiome` CLI:
|
using the `monobiome` CLI:
|
||||||
|
|
||||||
- First generate the scheme file, the definitions that respect perceptual
|
- First generate the scheme file, the lightness choices that achieve perceptual
|
||||||
uniformity of accents with respect to the base monotone:
|
uniformity of accents with respect to the base monotone:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -137,19 +137,14 @@ the `monobiome` CLI:
|
|||||||
monobiome fill scheme.toml templates/kitty/active.theme -o kitty.theme
|
monobiome fill scheme.toml templates/kitty/active.theme -o kitty.theme
|
||||||
```
|
```
|
||||||
|
|
||||||
This writes a concrete theme to `kitty.theme` that matches the user
|
This writes a concrete `kitty` theme to `kitty.theme` that matches the user
|
||||||
preferences, i.e., the contrast (`-d`), background lightness (`-l`), mode
|
preferences as captured in the previously generated scheme file, i.e., the
|
||||||
(`dark`), and biome (`grassland`). Every part of this process can be
|
contrast (`-d`), background lightness (`-l`), mode (`dark`), and biome
|
||||||
customized: the scheme parameters, the scheme definitions/file, the app
|
(`grassland`). Every part of this process can be customized: the scheme
|
||||||
template.
|
parameters, the scheme definitions/file, the app template.
|
||||||
|
|
||||||
Running these commands in sequence from the repo root should work
|
Running these commands in sequence from the repo root should work
|
||||||
out-of-the-box, after having installed the CLI tool.
|
out-of-the-box after having installed the CLI tool.
|
||||||
|
|
||||||
The `monobiome` CLI
|
|
||||||
produces the scheme file for requested parameters, and the [`symconf`][3] CLI
|
|
||||||
pushes palette colors through the scheme and into the app templates to yield a
|
|
||||||
concrete theme.
|
|
||||||
|
|
||||||
## Applications
|
## Applications
|
||||||
This repo provides palette-agnostic theme templates for `kitty`,
|
This repo provides palette-agnostic theme templates for `kitty`,
|
||||||
@@ -178,7 +173,7 @@ One can set these themes for the provided applications as follows:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Themes are generated using the [`kitty` theme
|
Themes are generated using the [`kitty` theme
|
||||||
template](templates/apps/kitty/templates/active.theme).
|
template](templates/kitty/active.theme).
|
||||||
|
|
||||||
- `vim`/`neovim`
|
- `vim`/`neovim`
|
||||||
|
|
||||||
@@ -193,7 +188,7 @@ One can set these themes for the provided applications as follows:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Themes are generated using the [`vim` theme
|
Themes are generated using the [`vim` theme
|
||||||
template](templates/apps/nvim/templates/theme.vim).
|
template](templates/nvim/theme.vim).
|
||||||
|
|
||||||
- `fzf`
|
- `fzf`
|
||||||
|
|
||||||
@@ -206,7 +201,7 @@ One can set these themes for the provided applications as follows:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Themes are generated using the [`fzf` theme
|
Themes are generated using the [`fzf` theme
|
||||||
template](templates/apps/fzf/templates/active.theme).
|
template](templates/fzf/active.theme).
|
||||||
|
|
||||||
- Firefox
|
- Firefox
|
||||||
|
|
||||||
@@ -214,13 +209,11 @@ One can set these themes for the provided applications as follows:
|
|||||||
add-ons][2], and switch between light/dark schemes based on system settings.
|
add-ons][2], and switch between light/dark schemes based on system settings.
|
||||||
You can also download raw XPI files for each theme in `app-config/firefox/`,
|
You can also download raw XPI files for each theme in `app-config/firefox/`,
|
||||||
each of which is generated using the [Firefox `manifest.json`
|
each of which is generated using the [Firefox `manifest.json`
|
||||||
template](templates/apps/firefox/templates/none-dark.manifest.json).
|
template](templates/firefox/auto-manifest.json).
|
||||||
|
|
||||||
Static [light][4] and [dark][5] themes are additionally available (i.e., that
|
Static [light][4] and [dark][5] themes are additionally available (i.e., that
|
||||||
don't change with system settings).
|
don't change with system settings).
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## CLI installation
|
## CLI installation
|
||||||
A brief theme generation guide was provided in the [Generation
|
A brief theme generation guide was provided in the [Generation
|
||||||
section](#generation), making use of the `monobiome` CLI. This tool can be
|
section](#generation), making use of the `monobiome` CLI. This tool can be
|
||||||
@@ -232,7 +225,7 @@ uv tool install monobiome
|
|||||||
pipx install monobiome
|
pipx install monobiome
|
||||||
```
|
```
|
||||||
|
|
||||||
The `monobiome` has provides three subcommands:
|
`monobiome` provides three subcommands:
|
||||||
|
|
||||||
- `monobiome palette`: generate palette files from raw parameterized curves
|
- `monobiome palette`: generate palette files from raw parameterized curves
|
||||||
|
|
||||||
@@ -295,6 +288,14 @@ The `monobiome` has provides three subcommands:
|
|||||||
output file to write filled template
|
output file to write filled template
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Config management
|
||||||
|
The `monobiome` CLI tool attempts to provide the minimal functionality needed
|
||||||
|
to produce customized themes for individual applications. If seeking a more
|
||||||
|
holistic, system-wide approach, you might consider using [`symconf`][3], a
|
||||||
|
general-purpose application config manager. `symconf` provides the templating
|
||||||
|
subsystem used for `monobiome` internals, and can be configured to apply live
|
||||||
|
theme updates to many apps with a single command line invocation.
|
||||||
|
|
||||||
|
|
||||||
[1]: https://github.com/isa/TextMate-Themes/blob/master/monoindustrial.tmTheme
|
[1]: https://github.com/isa/TextMate-Themes/blob/master/monoindustrial.tmTheme
|
||||||
[2]: https://addons.mozilla.org/en-US/firefox/collections/18495484/monobiome/
|
[2]: https://addons.mozilla.org/en-US/firefox/collections/18495484/monobiome/
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
version = "1.5.0"
|
version = "1.5.2"
|
||||||
|
|
||||||
[alpine]
|
[alpine]
|
||||||
l10 = "#030303"
|
l10 = "#030303"
|
||||||
@@ -271,7 +271,7 @@ l94 = "#f1eae4"
|
|||||||
l95 = "#f4ede7"
|
l95 = "#f4ede7"
|
||||||
l96 = "#f7f0ea"
|
l96 = "#f7f0ea"
|
||||||
l97 = "#fbf4ee"
|
l97 = "#fbf4ee"
|
||||||
l98 = "#fef7f1"
|
l98 = "#fdf7f2"
|
||||||
|
|
||||||
[savanna]
|
[savanna]
|
||||||
l10 = "#040301"
|
l10 = "#040301"
|
||||||
@@ -362,7 +362,7 @@ l94 = "#ecece3"
|
|||||||
l95 = "#efefe7"
|
l95 = "#efefe7"
|
||||||
l96 = "#f3f2ea"
|
l96 = "#f3f2ea"
|
||||||
l97 = "#f6f6ed"
|
l97 = "#f6f6ed"
|
||||||
l98 = "#f9f9f1"
|
l98 = "#f9f9f2"
|
||||||
|
|
||||||
[grassland]
|
[grassland]
|
||||||
l10 = "#020402"
|
l10 = "#020402"
|
||||||
@@ -453,7 +453,7 @@ l94 = "#e6ede7"
|
|||||||
l95 = "#eaf1ea"
|
l95 = "#eaf1ea"
|
||||||
l96 = "#edf4ee"
|
l96 = "#edf4ee"
|
||||||
l97 = "#f0f7f1"
|
l97 = "#f0f7f1"
|
||||||
l98 = "#f4fbf4"
|
l98 = "#f4faf5"
|
||||||
|
|
||||||
[reef]
|
[reef]
|
||||||
l10 = "#010404"
|
l10 = "#010404"
|
||||||
@@ -544,7 +544,7 @@ l94 = "#e3edef"
|
|||||||
l95 = "#e7f1f2"
|
l95 = "#e7f1f2"
|
||||||
l96 = "#eaf4f5"
|
l96 = "#eaf4f5"
|
||||||
l97 = "#edf7f9"
|
l97 = "#edf7f9"
|
||||||
l98 = "#f0fbfc"
|
l98 = "#f2fafb"
|
||||||
|
|
||||||
[tundra]
|
[tundra]
|
||||||
l10 = "#020306"
|
l10 = "#020306"
|
||||||
@@ -726,7 +726,7 @@ l94 = "#ede9f1"
|
|||||||
l95 = "#f0edf4"
|
l95 = "#f0edf4"
|
||||||
l96 = "#f3f0f8"
|
l96 = "#f3f0f8"
|
||||||
l97 = "#f7f3fb"
|
l97 = "#f7f3fb"
|
||||||
l98 = "#faf7ff"
|
l98 = "#faf7fe"
|
||||||
|
|
||||||
[moorland]
|
[moorland]
|
||||||
l10 = "#050204"
|
l10 = "#050204"
|
||||||
@@ -817,7 +817,7 @@ l94 = "#f1e8ec"
|
|||||||
l95 = "#f5ecef"
|
l95 = "#f5ecef"
|
||||||
l96 = "#f8eff3"
|
l96 = "#f8eff3"
|
||||||
l97 = "#fbf2f6"
|
l97 = "#fbf2f6"
|
||||||
l98 = "#fff6f9"
|
l98 = "#fef6f9"
|
||||||
|
|
||||||
[red]
|
[red]
|
||||||
l10 = "#0d0000"
|
l10 = "#0d0000"
|
||||||
@@ -1443,18 +1443,18 @@ l83 = "#d6b8f7"
|
|||||||
l84 = "#d8bcf8"
|
l84 = "#d8bcf8"
|
||||||
l85 = "#dbc1f9"
|
l85 = "#dbc1f9"
|
||||||
l86 = "#ddc5f9"
|
l86 = "#ddc5f9"
|
||||||
l87 = "#e0c9fa"
|
l87 = "#dfc9f9"
|
||||||
l88 = "#e2cdfb"
|
l88 = "#e2cdfa"
|
||||||
l89 = "#e5d1fb"
|
l89 = "#e4d2fa"
|
||||||
l90 = "#e7d5fc"
|
l90 = "#e6d6fa"
|
||||||
l91 = "#e9d9fc"
|
l91 = "#e9dafb"
|
||||||
l92 = "#ecdefd"
|
l92 = "#ebdefb"
|
||||||
l93 = "#eee2fd"
|
l93 = "#eee2fb"
|
||||||
l94 = "#f1e6fe"
|
l94 = "#f0e6fc"
|
||||||
l95 = "#f3eafe"
|
l95 = "#f2ebfc"
|
||||||
l96 = "#f5eefe"
|
l96 = "#f5effd"
|
||||||
l97 = "#f8f2fe"
|
l97 = "#f7f3fd"
|
||||||
l98 = "#faf7ff"
|
l98 = "#faf7fe"
|
||||||
|
|
||||||
[magenta]
|
[magenta]
|
||||||
l10 = "#080104"
|
l10 = "#080104"
|
||||||
@@ -1540,9 +1540,9 @@ l89 = "#f7cde0"
|
|||||||
l90 = "#f8d2e2"
|
l90 = "#f8d2e2"
|
||||||
l91 = "#f9d6e5"
|
l91 = "#f9d6e5"
|
||||||
l92 = "#fadbe8"
|
l92 = "#fadbe8"
|
||||||
l93 = "#fbdfeb"
|
l93 = "#fadfeb"
|
||||||
l94 = "#fce4ee"
|
l94 = "#fbe4ee"
|
||||||
l95 = "#fce8f1"
|
l95 = "#fce8f1"
|
||||||
l96 = "#fdedf4"
|
l96 = "#fdedf3"
|
||||||
l97 = "#fef1f6"
|
l97 = "#fdf1f6"
|
||||||
l98 = "#fef6f9"
|
l98 = "#fef6f9"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
version = "1.5.0"
|
version = "1.5.2"
|
||||||
|
|
||||||
[alpine]
|
[alpine]
|
||||||
l10 = "oklch(10.0% 0.0000 0.0)"
|
l10 = "oklch(10.0% 0.0000 0.0)"
|
||||||
@@ -180,7 +180,7 @@ l94 = "oklch(94.0% 0.0110 29.0)"
|
|||||||
l95 = "oklch(95.0% 0.0110 29.0)"
|
l95 = "oklch(95.0% 0.0110 29.0)"
|
||||||
l96 = "oklch(96.0% 0.0110 29.0)"
|
l96 = "oklch(96.0% 0.0110 29.0)"
|
||||||
l97 = "oklch(97.0% 0.0110 29.0)"
|
l97 = "oklch(97.0% 0.0110 29.0)"
|
||||||
l98 = "oklch(98.0% 0.0097 29.0)"
|
l98 = "oklch(98.0% 0.0092 29.0)"
|
||||||
|
|
||||||
[chaparral]
|
[chaparral]
|
||||||
l10 = "oklch(10.0% 0.0110 62.5)"
|
l10 = "oklch(10.0% 0.0110 62.5)"
|
||||||
@@ -271,7 +271,7 @@ l94 = "oklch(94.0% 0.0110 62.5)"
|
|||||||
l95 = "oklch(95.0% 0.0110 62.5)"
|
l95 = "oklch(95.0% 0.0110 62.5)"
|
||||||
l96 = "oklch(96.0% 0.0110 62.5)"
|
l96 = "oklch(96.0% 0.0110 62.5)"
|
||||||
l97 = "oklch(97.0% 0.0110 62.5)"
|
l97 = "oklch(97.0% 0.0110 62.5)"
|
||||||
l98 = "oklch(98.0% 0.0110 62.5)"
|
l98 = "oklch(98.0% 0.0092 62.5)"
|
||||||
|
|
||||||
[savanna]
|
[savanna]
|
||||||
l10 = "oklch(10.0% 0.0110 104.0)"
|
l10 = "oklch(10.0% 0.0110 104.0)"
|
||||||
@@ -362,7 +362,7 @@ l94 = "oklch(94.0% 0.0110 104.0)"
|
|||||||
l95 = "oklch(95.0% 0.0110 104.0)"
|
l95 = "oklch(95.0% 0.0110 104.0)"
|
||||||
l96 = "oklch(96.0% 0.0110 104.0)"
|
l96 = "oklch(96.0% 0.0110 104.0)"
|
||||||
l97 = "oklch(97.0% 0.0110 104.0)"
|
l97 = "oklch(97.0% 0.0110 104.0)"
|
||||||
l98 = "oklch(98.0% 0.0110 104.0)"
|
l98 = "oklch(98.0% 0.0092 104.0)"
|
||||||
|
|
||||||
[grassland]
|
[grassland]
|
||||||
l10 = "oklch(10.0% 0.0110 148.0)"
|
l10 = "oklch(10.0% 0.0110 148.0)"
|
||||||
@@ -453,7 +453,7 @@ l94 = "oklch(94.0% 0.0110 148.0)"
|
|||||||
l95 = "oklch(95.0% 0.0110 148.0)"
|
l95 = "oklch(95.0% 0.0110 148.0)"
|
||||||
l96 = "oklch(96.0% 0.0110 148.0)"
|
l96 = "oklch(96.0% 0.0110 148.0)"
|
||||||
l97 = "oklch(97.0% 0.0110 148.0)"
|
l97 = "oklch(97.0% 0.0110 148.0)"
|
||||||
l98 = "oklch(98.0% 0.0110 148.0)"
|
l98 = "oklch(98.0% 0.0092 148.0)"
|
||||||
|
|
||||||
[reef]
|
[reef]
|
||||||
l10 = "oklch(10.0% 0.0110 205.0)"
|
l10 = "oklch(10.0% 0.0110 205.0)"
|
||||||
@@ -544,7 +544,7 @@ l94 = "oklch(94.0% 0.0110 205.0)"
|
|||||||
l95 = "oklch(95.0% 0.0110 205.0)"
|
l95 = "oklch(95.0% 0.0110 205.0)"
|
||||||
l96 = "oklch(96.0% 0.0110 205.0)"
|
l96 = "oklch(96.0% 0.0110 205.0)"
|
||||||
l97 = "oklch(97.0% 0.0110 205.0)"
|
l97 = "oklch(97.0% 0.0110 205.0)"
|
||||||
l98 = "oklch(98.0% 0.0110 205.0)"
|
l98 = "oklch(98.0% 0.0092 205.0)"
|
||||||
|
|
||||||
[tundra]
|
[tundra]
|
||||||
l10 = "oklch(10.0% 0.0110 262.0)"
|
l10 = "oklch(10.0% 0.0110 262.0)"
|
||||||
@@ -635,7 +635,7 @@ l94 = "oklch(94.0% 0.0110 262.0)"
|
|||||||
l95 = "oklch(95.0% 0.0110 262.0)"
|
l95 = "oklch(95.0% 0.0110 262.0)"
|
||||||
l96 = "oklch(96.0% 0.0110 262.0)"
|
l96 = "oklch(96.0% 0.0110 262.0)"
|
||||||
l97 = "oklch(97.0% 0.0110 262.0)"
|
l97 = "oklch(97.0% 0.0110 262.0)"
|
||||||
l98 = "oklch(98.0% 0.0094 262.0)"
|
l98 = "oklch(98.0% 0.0092 262.0)"
|
||||||
|
|
||||||
[heathland]
|
[heathland]
|
||||||
l10 = "oklch(10.0% 0.0110 306.0)"
|
l10 = "oklch(10.0% 0.0110 306.0)"
|
||||||
@@ -726,7 +726,7 @@ l94 = "oklch(94.0% 0.0110 306.0)"
|
|||||||
l95 = "oklch(95.0% 0.0110 306.0)"
|
l95 = "oklch(95.0% 0.0110 306.0)"
|
||||||
l96 = "oklch(96.0% 0.0110 306.0)"
|
l96 = "oklch(96.0% 0.0110 306.0)"
|
||||||
l97 = "oklch(97.0% 0.0110 306.0)"
|
l97 = "oklch(97.0% 0.0110 306.0)"
|
||||||
l98 = "oklch(98.0% 0.0110 306.0)"
|
l98 = "oklch(98.0% 0.0092 306.0)"
|
||||||
|
|
||||||
[moorland]
|
[moorland]
|
||||||
l10 = "oklch(10.0% 0.0110 350.0)"
|
l10 = "oklch(10.0% 0.0110 350.0)"
|
||||||
@@ -817,7 +817,7 @@ l94 = "oklch(94.0% 0.0110 350.0)"
|
|||||||
l95 = "oklch(95.0% 0.0110 350.0)"
|
l95 = "oklch(95.0% 0.0110 350.0)"
|
||||||
l96 = "oklch(96.0% 0.0110 350.0)"
|
l96 = "oklch(96.0% 0.0110 350.0)"
|
||||||
l97 = "oklch(97.0% 0.0110 350.0)"
|
l97 = "oklch(97.0% 0.0110 350.0)"
|
||||||
l98 = "oklch(98.0% 0.0110 350.0)"
|
l98 = "oklch(98.0% 0.0092 350.0)"
|
||||||
|
|
||||||
[red]
|
[red]
|
||||||
l10 = "oklch(10.0% 0.0406 29.0)"
|
l10 = "oklch(10.0% 0.0406 29.0)"
|
||||||
@@ -1087,10 +1087,10 @@ l91 = "oklch(91.0% 0.0402 104.0)"
|
|||||||
l92 = "oklch(92.0% 0.0360 104.0)"
|
l92 = "oklch(92.0% 0.0360 104.0)"
|
||||||
l93 = "oklch(93.0% 0.0317 104.0)"
|
l93 = "oklch(93.0% 0.0317 104.0)"
|
||||||
l94 = "oklch(94.0% 0.0273 104.0)"
|
l94 = "oklch(94.0% 0.0273 104.0)"
|
||||||
l95 = "oklch(95.0% 0.0229 104.0)"
|
l95 = "oklch(95.0% 0.0228 104.0)"
|
||||||
l96 = "oklch(96.0% 0.0184 104.0)"
|
l96 = "oklch(96.0% 0.0183 104.0)"
|
||||||
l97 = "oklch(97.0% 0.0138 104.0)"
|
l97 = "oklch(97.0% 0.0138 104.0)"
|
||||||
l98 = "oklch(98.0% 0.0093 104.0)"
|
l98 = "oklch(98.0% 0.0092 104.0)"
|
||||||
|
|
||||||
[green]
|
[green]
|
||||||
l10 = "oklch(10.0% 0.0178 148.0)"
|
l10 = "oklch(10.0% 0.0178 148.0)"
|
||||||
@@ -1442,19 +1442,19 @@ l82 = "oklch(82.0% 0.0964 306.0)"
|
|||||||
l83 = "oklch(83.0% 0.0915 306.0)"
|
l83 = "oklch(83.0% 0.0915 306.0)"
|
||||||
l84 = "oklch(84.0% 0.0865 306.0)"
|
l84 = "oklch(84.0% 0.0865 306.0)"
|
||||||
l85 = "oklch(85.0% 0.0815 306.0)"
|
l85 = "oklch(85.0% 0.0815 306.0)"
|
||||||
l86 = "oklch(86.0% 0.0764 306.0)"
|
l86 = "oklch(86.0% 0.0758 306.0)"
|
||||||
l87 = "oklch(87.0% 0.0712 306.0)"
|
l87 = "oklch(87.0% 0.0697 306.0)"
|
||||||
l88 = "oklch(88.0% 0.0660 306.0)"
|
l88 = "oklch(88.0% 0.0638 306.0)"
|
||||||
l89 = "oklch(89.0% 0.0607 306.0)"
|
l89 = "oklch(89.0% 0.0579 306.0)"
|
||||||
l90 = "oklch(90.0% 0.0554 306.0)"
|
l90 = "oklch(90.0% 0.0522 306.0)"
|
||||||
l91 = "oklch(91.0% 0.0500 306.0)"
|
l91 = "oklch(91.0% 0.0466 306.0)"
|
||||||
l92 = "oklch(92.0% 0.0446 306.0)"
|
l92 = "oklch(92.0% 0.0410 306.0)"
|
||||||
l93 = "oklch(93.0% 0.0391 306.0)"
|
l93 = "oklch(93.0% 0.0356 306.0)"
|
||||||
l94 = "oklch(94.0% 0.0336 306.0)"
|
l94 = "oklch(94.0% 0.0302 306.0)"
|
||||||
l95 = "oklch(95.0% 0.0281 306.0)"
|
l95 = "oklch(95.0% 0.0250 306.0)"
|
||||||
l96 = "oklch(96.0% 0.0225 306.0)"
|
l96 = "oklch(96.0% 0.0198 306.0)"
|
||||||
l97 = "oklch(97.0% 0.0169 306.0)"
|
l97 = "oklch(97.0% 0.0147 306.0)"
|
||||||
l98 = "oklch(98.0% 0.0113 306.0)"
|
l98 = "oklch(98.0% 0.0097 306.0)"
|
||||||
|
|
||||||
[magenta]
|
[magenta]
|
||||||
l10 = "oklch(10.0% 0.0242 350.0)"
|
l10 = "oklch(10.0% 0.0242 350.0)"
|
||||||
@@ -1538,11 +1538,11 @@ l87 = "oklch(87.0% 0.0619 350.0)"
|
|||||||
l88 = "oklch(88.0% 0.0574 350.0)"
|
l88 = "oklch(88.0% 0.0574 350.0)"
|
||||||
l89 = "oklch(89.0% 0.0528 350.0)"
|
l89 = "oklch(89.0% 0.0528 350.0)"
|
||||||
l90 = "oklch(90.0% 0.0481 350.0)"
|
l90 = "oklch(90.0% 0.0481 350.0)"
|
||||||
l91 = "oklch(91.0% 0.0435 350.0)"
|
l91 = "oklch(91.0% 0.0433 350.0)"
|
||||||
l92 = "oklch(92.0% 0.0387 350.0)"
|
l92 = "oklch(92.0% 0.0384 350.0)"
|
||||||
l93 = "oklch(93.0% 0.0340 350.0)"
|
l93 = "oklch(93.0% 0.0334 350.0)"
|
||||||
l94 = "oklch(94.0% 0.0292 350.0)"
|
l94 = "oklch(94.0% 0.0285 350.0)"
|
||||||
l95 = "oklch(95.0% 0.0244 350.0)"
|
l95 = "oklch(95.0% 0.0237 350.0)"
|
||||||
l96 = "oklch(96.0% 0.0196 350.0)"
|
l96 = "oklch(96.0% 0.0189 350.0)"
|
||||||
l97 = "oklch(97.0% 0.0147 350.0)"
|
l97 = "oklch(97.0% 0.0141 350.0)"
|
||||||
l98 = "oklch(98.0% 0.0098 350.0)"
|
l98 = "oklch(98.0% 0.0094 350.0)"
|
||||||
|
|||||||
BIN
images/curves/cstar-curves-v151.png
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
images/release/1.5.1/chroma-bounds.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
images/release/1.5.1/chroma-curves.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
images/release/1.5.1/palette-bare.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
images/release/1.5.1/palette.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
images/release/1.5.2/chroma-bounds.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
images/release/1.5.2/chroma-curves.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
images/release/1.5.2/palette-bare.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
images/release/1.5.2/palette.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
@@ -17,7 +17,7 @@ def register_parser(subparsers: _SubparserType) -> None:
|
|||||||
type=str,
|
type=str,
|
||||||
default="hex",
|
default="hex",
|
||||||
choices=["hex", "oklch"],
|
choices=["hex", "oklch"],
|
||||||
help="Color notation to export (either hex or oklch)",
|
help="color notation to export (either hex or oklch)",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-f",
|
"-f",
|
||||||
@@ -25,13 +25,13 @@ def register_parser(subparsers: _SubparserType) -> None:
|
|||||||
type=str,
|
type=str,
|
||||||
default="toml",
|
default="toml",
|
||||||
choices=["json", "toml"],
|
choices=["json", "toml"],
|
||||||
help="Format of palette file (either JSON or TOML)",
|
help="format of palette file (either JSON or TOML)",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-o",
|
"-o",
|
||||||
"--output",
|
"--output",
|
||||||
type=str,
|
type=str,
|
||||||
help="Output file to write palette content",
|
help="output file to write palette content",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.set_defaults(func=handle_palette)
|
parser.set_defaults(func=handle_palette)
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ def register_parser(subparsers: _SubparserType) -> None:
|
|||||||
"mode",
|
"mode",
|
||||||
type=str,
|
type=str,
|
||||||
choices=["dark", "light"],
|
choices=["dark", "light"],
|
||||||
help="Scheme mode (light or dark)"
|
help="scheme mode (light or dark)"
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"biome",
|
"biome",
|
||||||
type=str,
|
type=str,
|
||||||
choices=list(monotone_h_map.keys()),
|
choices=list(monotone_h_map.keys()),
|
||||||
help="Biome setting for scheme."
|
help="biome setting for scheme"
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-m",
|
"-m",
|
||||||
@@ -30,7 +30,7 @@ def register_parser(subparsers: _SubparserType) -> None:
|
|||||||
type=str,
|
type=str,
|
||||||
default="oklch",
|
default="oklch",
|
||||||
choices=["wcag", "oklch", "lightness"],
|
choices=["wcag", "oklch", "lightness"],
|
||||||
help="Metric to use for measuring swatch distances."
|
help="metric to use for measuring swatch distances"
|
||||||
)
|
)
|
||||||
|
|
||||||
# e.g., wcag=4.5; oklch=0.40; lightness=40
|
# e.g., wcag=4.5; oklch=0.40; lightness=40
|
||||||
@@ -39,13 +39,13 @@ def register_parser(subparsers: _SubparserType) -> None:
|
|||||||
"--distance",
|
"--distance",
|
||||||
type=float,
|
type=float,
|
||||||
default=0.40,
|
default=0.40,
|
||||||
help="Distance threshold for specified metric",
|
help="distance threshold for specified metric",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-o",
|
"-o",
|
||||||
"--output",
|
"--output",
|
||||||
type=str,
|
type=str,
|
||||||
help="Output file to write scheme content",
|
help="output file to write scheme content",
|
||||||
)
|
)
|
||||||
|
|
||||||
# these params remain rooted in lightness; no need to accommodate metric
|
# these params remain rooted in lightness; no need to accommodate metric
|
||||||
@@ -58,13 +58,13 @@ def register_parser(subparsers: _SubparserType) -> None:
|
|||||||
"--l-base",
|
"--l-base",
|
||||||
type=int,
|
type=int,
|
||||||
default=20,
|
default=20,
|
||||||
help="Minimum lightness level (default: 20)",
|
help="minimum lightness level (default: 20)",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--l-step",
|
"--l-step",
|
||||||
type=int,
|
type=int,
|
||||||
default=5,
|
default=5,
|
||||||
help="Lightness step size (default: 5)",
|
help="lightness step size (default: 5)",
|
||||||
)
|
)
|
||||||
|
|
||||||
# gaps
|
# gaps
|
||||||
@@ -72,19 +72,19 @@ def register_parser(subparsers: _SubparserType) -> None:
|
|||||||
"--fg-gap",
|
"--fg-gap",
|
||||||
type=int,
|
type=int,
|
||||||
default=50,
|
default=50,
|
||||||
help="Foreground lightness gap (default: 50)",
|
help="foreground lightness gap (default: 50)",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--grey-gap",
|
"--grey-gap",
|
||||||
type=int,
|
type=int,
|
||||||
default=30,
|
default=30,
|
||||||
help="Grey lightness gap (default: 30)",
|
help="grey lightness gap (default: 30)",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--term-fg-gap",
|
"--term-fg-gap",
|
||||||
type=int,
|
type=int,
|
||||||
default=65,
|
default=65,
|
||||||
help="Terminal foreground lightness gap (default: 60)",
|
help="terminal foreground lightness gap (default: 60)",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.set_defaults(func=handle_scheme)
|
parser.set_defaults(func=handle_scheme)
|
||||||
|
|||||||
@@ -121,3 +121,21 @@ for h_str, L_points_C in Lpoints_Cqbr_Hmap.items():
|
|||||||
max(0, min(_C, l_maxC_h(_L, _h)))
|
max(0, min(_C, l_maxC_h(_L, _h)))
|
||||||
for _L, _C in zip(L_points, L_points_C, strict=True)
|
for _L, _C in zip(L_points, L_points_C, strict=True)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# strictly enforce curve bounds s.t. there are no intersections
|
||||||
|
# order is determined by the max attained chromap
|
||||||
|
max_Cstar_Horder = [
|
||||||
|
(h_str, max(Lpoints_Cstar))
|
||||||
|
for h_str, Lpoints_Cstar in Lpoints_Cstar_Hmap.items()
|
||||||
|
]
|
||||||
|
max_Cstar_Horder = sorted(max_Cstar_Horder, key=lambda t: t[1], reverse=True)
|
||||||
|
|
||||||
|
for i in range(len(max_Cstar_Horder)-1):
|
||||||
|
outer_h, _ = max_Cstar_Horder[i]
|
||||||
|
inner_h, _ = max_Cstar_Horder[i+1]
|
||||||
|
|
||||||
|
Lpoints_Cstar_Hmap[inner_h] = [
|
||||||
|
min(inner_c, Lpoints_Cstar_Hmap[outer_h][ci])
|
||||||
|
for ci, inner_c in enumerate(Lpoints_Cstar_Hmap[inner_h])
|
||||||
|
]
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ from importlib.metadata import version
|
|||||||
|
|
||||||
from coloraide import Color
|
from coloraide import Color
|
||||||
|
|
||||||
|
from monobiome.util import (
|
||||||
|
hex_from_rgb8,
|
||||||
|
srgb8_from_color,
|
||||||
|
)
|
||||||
from monobiome.constants import (
|
from monobiome.constants import (
|
||||||
h_map,
|
h_map,
|
||||||
L_points,
|
L_points,
|
||||||
@@ -24,8 +28,8 @@ def compute_hlc_map(notation: str) -> dict[str, Any]:
|
|||||||
oklch = Color('oklch', [_l/100, _c, _h])
|
oklch = Color('oklch', [_l/100, _c, _h])
|
||||||
|
|
||||||
if notation == "hex":
|
if notation == "hex":
|
||||||
srgb = oklch.convert('srgb')
|
rgb8 = srgb8_from_color(oklch)
|
||||||
c_str = srgb.to_string(hex=True)
|
c_str = hex_from_rgb8(rgb8)
|
||||||
elif notation == "oklch":
|
elif notation == "oklch":
|
||||||
ol, oc, oh = oklch.convert('oklch').coords()
|
ol, oc, oh = oklch.convert('oklch').coords()
|
||||||
c_str = f"oklch({ol*100:.1f}% {oc:.4f} {oh:.1f})"
|
c_str = f"oklch({ol*100:.1f}% {oc:.4f} {oh:.1f})"
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
|
from importlib.metadata import version
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from coloraide import Color
|
from coloraide import Color
|
||||||
|
from matplotlib.collections import LineCollection
|
||||||
|
|
||||||
|
from monobiome.util import srgb8_from_color
|
||||||
from monobiome.palette import compute_hlc_map
|
from monobiome.palette import compute_hlc_map
|
||||||
from monobiome.constants import (
|
from monobiome.constants import (
|
||||||
h_map,
|
h_map,
|
||||||
@@ -10,11 +14,13 @@ from monobiome.constants import (
|
|||||||
accent_h_map,
|
accent_h_map,
|
||||||
monotone_h_map,
|
monotone_h_map,
|
||||||
Lspace_Cmax_Hmap,
|
Lspace_Cmax_Hmap,
|
||||||
|
max_Cstar_Horder,
|
||||||
Lpoints_Cstar_Hmap,
|
Lpoints_Cstar_Hmap,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
VERSION = version("monobiome")
|
||||||
|
|
||||||
def plot_hue_chroma_bounds() -> None:
|
def plot_hue_chroma_bounds() -> tuple[plt.Figure, plt.Axes]:
|
||||||
name_h_map = {}
|
name_h_map = {}
|
||||||
ax_h_map = {}
|
ax_h_map = {}
|
||||||
fig, axes = plt.subplots(
|
fig, axes = plt.subplots(
|
||||||
@@ -63,43 +69,56 @@ def plot_hue_chroma_bounds() -> None:
|
|||||||
ncol=3
|
ncol=3
|
||||||
)
|
)
|
||||||
|
|
||||||
plt.suptitle("$C^*$ curves for hue groups")
|
plt.suptitle(f"$C^*$ curves for hue groups (v{VERSION})")
|
||||||
plt.show()
|
|
||||||
|
|
||||||
|
return fig, axes
|
||||||
|
|
||||||
def plot_hue_chroma_star() -> None:
|
def plot_hue_chroma_star() -> tuple[plt.Figure, plt.Axes]:
|
||||||
fig, ax = plt.subplots(1, 1, figsize=(8, 6))
|
fig, ax = plt.subplots(1, 1, figsize=(8, 6))
|
||||||
|
|
||||||
# uncomment to preview 5 core term colors
|
|
||||||
colors = accent_h_map.keys()
|
colors = accent_h_map.keys()
|
||||||
|
# uncomment to preview just the 5 core term colors
|
||||||
# colors = set(["red", "orange", "yellow", "green", "blue"])
|
# colors = set(["red", "orange", "yellow", "green", "blue"])
|
||||||
|
|
||||||
for h_str in Lpoints_Cstar_Hmap:
|
for h_str, _ in max_Cstar_Horder:
|
||||||
|
Lpoints_Cstar = Lpoints_Cstar_Hmap[h_str]
|
||||||
|
|
||||||
if h_str not in accent_h_map or h_str not in colors:
|
if h_str not in accent_h_map or h_str not in colors:
|
||||||
continue
|
continue
|
||||||
ax.fill_between(
|
|
||||||
L_points,
|
|
||||||
Lpoints_Cstar_Hmap[h_str],
|
|
||||||
alpha=0.2,
|
|
||||||
color='grey',
|
|
||||||
label=h_str
|
|
||||||
)
|
|
||||||
|
|
||||||
x, y = L_points, Lpoints_Cstar_Hmap[h_str]
|
_h = h_map[h_str]
|
||||||
n = int(0.45*len(x))
|
h_colors = [
|
||||||
ax.text(x[n], y[n]-0.01, h_str, rotation=10, va='center', ha='left')
|
Color(
|
||||||
|
'oklch', [_l/100, _c, _h]
|
||||||
|
).convert("srgb").fit(method="oklch-chroma")
|
||||||
|
for _l, _c in zip(L_points, Lpoints_Cstar, strict=True)
|
||||||
|
]
|
||||||
|
|
||||||
|
x = np.asarray(L_points)
|
||||||
|
y = np.asarray(Lpoints_Cstar)
|
||||||
|
pts = np.column_stack([x, y]).reshape(-1, 1, 2)
|
||||||
|
segs = np.concatenate([pts[:-1], pts[1:]], axis=1)
|
||||||
|
rgb = np.asarray(h_colors)
|
||||||
|
seg_colors = (rgb[:-1] + rgb[1:]) / 2
|
||||||
|
lc = LineCollection(segs, colors=seg_colors, linewidth=3,
|
||||||
|
capstyle="round", joinstyle="round",
|
||||||
|
label=h_str)
|
||||||
|
|
||||||
|
ax.add_collection(lc)
|
||||||
|
ax.autoscale_view()
|
||||||
|
|
||||||
ax.set_xlabel("Lightness (%)")
|
ax.set_xlabel("Lightness (%)")
|
||||||
ax.set_xticks([L_points[0], 45, 50, 55, 60, 65, 70, L_points[-1]])
|
ax.set_xticks([L_points[0], 45, 50, 55, 60, 65, 70, L_points[-1]])
|
||||||
plt.suptitle("$C^*$ curves (v1.4.0)")
|
|
||||||
fig.show()
|
|
||||||
|
|
||||||
|
plt.suptitle(f"$C^*$ curves (v{VERSION})")
|
||||||
|
|
||||||
|
return fig, ax
|
||||||
|
|
||||||
def palette_image(
|
def palette_image(
|
||||||
palette: dict[str, dict[int, str]],
|
palette: dict[str, dict[int, str]],
|
||||||
cell_size: int = 40,
|
cell_size: int = 40,
|
||||||
keys: list[str] | None = None
|
keys: list[str] | None = None
|
||||||
) -> tuple[np.ndarray, list[str], list[list[int]], int, int]:
|
) -> tuple[np.ndarray, list[str], list[list[int]]]:
|
||||||
names = list(palette.keys()) if keys is None else keys
|
names = list(palette.keys()) if keys is None else keys
|
||||||
|
|
||||||
row_count = len(names)
|
row_count = len(names)
|
||||||
@@ -108,7 +127,7 @@ def palette_image(
|
|||||||
|
|
||||||
h = row_count * cell_size
|
h = row_count * cell_size
|
||||||
w = max_cols * cell_size
|
w = max_cols * cell_size
|
||||||
img = np.ones((h, w, 3), float)
|
img = np.ones((h, w, 3), int)
|
||||||
|
|
||||||
lightness_keys_per_row = []
|
lightness_keys_per_row = []
|
||||||
|
|
||||||
@@ -117,14 +136,12 @@ def palette_image(
|
|||||||
lkeys = sorted(shades.keys())
|
lkeys = sorted(shades.keys())
|
||||||
lightness_keys_per_row.append(lkeys)
|
lightness_keys_per_row.append(lkeys)
|
||||||
for c, k in enumerate(lkeys):
|
for c, k in enumerate(lkeys):
|
||||||
col = Color(shades[k]).convert("srgb").fit(method="clip")
|
rgb = srgb8_from_color(shades[k])
|
||||||
rgb = [col["r"], col["g"], col["b"]]
|
|
||||||
r0, r1 = r * cell_size, (r + 1) * cell_size
|
r0, r1 = r * cell_size, (r + 1) * cell_size
|
||||||
c0, c1 = c * cell_size, (c + 1) * cell_size
|
c0, c1 = c * cell_size, (c + 1) * cell_size
|
||||||
img[r0:r1, c0:c1, :] = rgb
|
img[r0:r1, c0:c1, :] = rgb
|
||||||
|
|
||||||
return img, names, lightness_keys_per_row, cell_size, max_cols
|
return img, names, lightness_keys_per_row
|
||||||
|
|
||||||
|
|
||||||
def show_palette(
|
def show_palette(
|
||||||
palette: dict[str, dict[int, str]],
|
palette: dict[str, dict[int, str]],
|
||||||
@@ -133,9 +150,7 @@ def show_palette(
|
|||||||
show_labels: bool = True,
|
show_labels: bool = True,
|
||||||
dpi: int = 100,
|
dpi: int = 100,
|
||||||
) -> tuple[plt.Figure, plt.Axes]:
|
) -> tuple[plt.Figure, plt.Axes]:
|
||||||
img, names, keys, cell_size, max_cols = palette_image(
|
img, names, _ = palette_image(palette, cell_size, keys=keys)
|
||||||
palette, cell_size, keys=keys
|
|
||||||
)
|
|
||||||
|
|
||||||
fig_w = img.shape[1] / 100
|
fig_w = img.shape[1] / 100
|
||||||
fig_h = img.shape[0] / 100
|
fig_h = img.shape[0] / 100
|
||||||
@@ -143,7 +158,7 @@ def show_palette(
|
|||||||
if show_labels:
|
if show_labels:
|
||||||
fig, ax = plt.subplots(figsize=(fig_w, fig_h), dpi=dpi)
|
fig, ax = plt.subplots(figsize=(fig_w, fig_h), dpi=dpi)
|
||||||
|
|
||||||
ax.imshow(img, interpolation="none", origin="upper")
|
ax.imshow(img, interpolation="nearest", origin="upper")
|
||||||
ax.set_xticks([])
|
ax.set_xticks([])
|
||||||
|
|
||||||
ytick_pos = [(i + 0.5) * cell_size for i in range(len(names))]
|
ytick_pos = [(i + 0.5) * cell_size for i in range(len(names))]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import math
|
|||||||
from types import GenericAlias
|
from types import GenericAlias
|
||||||
from argparse import ArgumentParser, _SubParsersAction
|
from argparse import ArgumentParser, _SubParsersAction
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
from coloraide import Color
|
from coloraide import Color
|
||||||
|
|
||||||
_SubParsersAction.__class_getitem__ = classmethod(GenericAlias)
|
_SubParsersAction.__class_getitem__ = classmethod(GenericAlias)
|
||||||
@@ -33,3 +34,13 @@ def oklch_distance(xc: Color, yc: Color) -> float:
|
|||||||
dz = l1 - l2
|
dz = l1 - l2
|
||||||
|
|
||||||
return (dx**2 + dy**2 + dz**2)**0.5
|
return (dx**2 + dy**2 + dz**2)**0.5
|
||||||
|
|
||||||
|
def srgb8_from_color(c: str | Color) -> np.ndarray:
|
||||||
|
c = Color(c).convert("srgb").fit(method="oklch-chroma")
|
||||||
|
rgb = np.array([c["r"], c["g"], c["b"]], dtype=float)
|
||||||
|
rgb8 = np.clip(np.round(rgb * 255), 0, 255).astype(np.uint8)
|
||||||
|
|
||||||
|
return rgb8
|
||||||
|
|
||||||
|
def hex_from_rgb8(rgb8: np.ndarray) -> str:
|
||||||
|
return f"#{int(rgb8[0]):02x}{int(rgb8[1]):02x}{int(rgb8[2]):02x}"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "monobiome"
|
name = "monobiome"
|
||||||
version = "1.5.0"
|
version = "1.5.2"
|
||||||
description = "Monobiome color palette"
|
description = "Monobiome color palette"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
authors = [
|
authors = [
|
||||||
|
|||||||
82
scheme.toml
@@ -1,82 +0,0 @@
|
|||||||
# ++ monobiome scheme file ++
|
|
||||||
# ++ generated CLI @ 1.5.0 ++
|
|
||||||
version = "1.5.0"
|
|
||||||
mode = "dark"
|
|
||||||
biome = "moorland"
|
|
||||||
metric = "oklch"
|
|
||||||
distance = "0.42"
|
|
||||||
l_base = "20"
|
|
||||||
l_step = "5"
|
|
||||||
fg_gap = "50"
|
|
||||||
grey_gap = "30"
|
|
||||||
term_fg_gap = "65"
|
|
||||||
bg0 = "f{{moorland.l20}}"
|
|
||||||
bg1 = "f{{moorland.l25}}"
|
|
||||||
bg2 = "f{{moorland.l30}}"
|
|
||||||
bg3 = "f{{moorland.l35}}"
|
|
||||||
fg3 = "f{{moorland.l70}}"
|
|
||||||
fg2 = "f{{moorland.l75}}"
|
|
||||||
fg1 = "f{{moorland.l80}}"
|
|
||||||
fg0 = "f{{moorland.l85}}"
|
|
||||||
black = "f{{moorland.l20}}"
|
|
||||||
grey = "f{{moorland.l50}}"
|
|
||||||
white = "f{{moorland.l75}}"
|
|
||||||
red = "f{{red.l59}}"
|
|
||||||
orange = "f{{orange.l61}}"
|
|
||||||
yellow = "f{{yellow.l62}}"
|
|
||||||
green = "f{{green.l61}}"
|
|
||||||
cyan = "f{{cyan.l61}}"
|
|
||||||
blue = "f{{blue.l60}}"
|
|
||||||
violet = "f{{violet.l60}}"
|
|
||||||
magenta = "f{{orange.l61}}"
|
|
||||||
|
|
||||||
[term]
|
|
||||||
background = "f{{moorland.l25}}"
|
|
||||||
selection_bg = "f{{moorland.l30}}"
|
|
||||||
selection_fg = "f{{moorland.l85}}"
|
|
||||||
foreground = "f{{moorland.l90}}"
|
|
||||||
cursor = "f{{moorland.l85}}"
|
|
||||||
cursor_text = "f{{moorland.l30}}"
|
|
||||||
|
|
||||||
[term.normal]
|
|
||||||
black = "f{{moorland.l25}}"
|
|
||||||
grey = "f{{moorland.l55}}"
|
|
||||||
white = "f{{moorland.l80}}"
|
|
||||||
red = "f{{red.l64}}"
|
|
||||||
yellow = "f{{yellow.l67}}"
|
|
||||||
green = "f{{green.l66}}"
|
|
||||||
cyan = "f{{blue.l65}}"
|
|
||||||
blue = "f{{blue.l65}}"
|
|
||||||
magenta = "f{{orange.l66}}"
|
|
||||||
|
|
||||||
[term.bright]
|
|
||||||
black = "f{{moorland.l35}}"
|
|
||||||
grey = "f{{moorland.l65}}"
|
|
||||||
white = "f{{moorland.l90}}"
|
|
||||||
red = "f{{red.l75}}"
|
|
||||||
yellow = "f{{yellow.l77}}"
|
|
||||||
green = "f{{green.l76}}"
|
|
||||||
cyan = "f{{blue.l76}}"
|
|
||||||
blue = "f{{blue.l76}}"
|
|
||||||
magenta = "f{{orange.l76}}"
|
|
||||||
|
|
||||||
[vim]
|
|
||||||
bg0 = "f{{moorland.l25}}"
|
|
||||||
bg1 = "f{{moorland.l30}}"
|
|
||||||
bg2 = "f{{moorland.l35}}"
|
|
||||||
bg3 = "f{{moorland.l40}}"
|
|
||||||
fg3 = "f{{moorland.l75}}"
|
|
||||||
fg2 = "f{{moorland.l80}}"
|
|
||||||
fg1 = "f{{moorland.l85}}"
|
|
||||||
fg0 = "f{{moorland.l90}}"
|
|
||||||
black = "f{{moorland.l25}}"
|
|
||||||
grey = "f{{moorland.l55}}"
|
|
||||||
white = "f{{moorland.l80}}"
|
|
||||||
red = "f{{red.l64}}"
|
|
||||||
orange = "f{{orange.l66}}"
|
|
||||||
yellow = "f{{yellow.l67}}"
|
|
||||||
green = "f{{green.l66}}"
|
|
||||||
cyan = "f{{green.l66}}"
|
|
||||||
blue = "f{{blue.l65}}"
|
|
||||||
violet = "f{{blue.l65}}"
|
|
||||||
magenta = "f{{red.l64}}"
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# note: this script is not portable; to be run in the monobiome scripts/
|
# note: this script is not portable; script to be placed in the monobiome
|
||||||
# directory (notice the `rm` invocations)
|
# scripts/ directory and run from the repo root (notice the `rm` invocations)
|
||||||
|
|
||||||
# clean existing config
|
# clean existing config
|
||||||
rm -rf app-config/*
|
rm -rf app-config/*
|
||||||
@@ -37,6 +37,9 @@ for biome in "${biomes[@]}"; do
|
|||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# remove lingering scheme file
|
||||||
|
rm scheme.toml
|
||||||
|
|
||||||
cd app-config/firefox
|
cd app-config/firefox
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
for f in *; do
|
for f in *; do
|
||||||
|
|||||||
24
scripts/plots.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import monobiome as mb
|
||||||
|
from monobiome import plotting
|
||||||
|
from monobiome.palette import compute_hlc_map
|
||||||
|
|
||||||
|
figure_dir = Path(f"images/release/{mb.__version__}")
|
||||||
|
figure_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
fig, ax = plotting.plot_hue_chroma_bounds()
|
||||||
|
fig.savefig(Path(figure_dir, "chroma-bounds.png"))
|
||||||
|
|
||||||
|
fig, ax = plotting.plot_hue_chroma_star()
|
||||||
|
fig.savefig(Path(figure_dir, "chroma-curves.png"))
|
||||||
|
|
||||||
|
# compute the palette as hex to ensure the rendering matches; using
|
||||||
|
# "oklch" causes some slight hex drift when later using an eyedropper
|
||||||
|
hlc_map = compute_hlc_map("hex") # ("oklch")
|
||||||
|
|
||||||
|
fig, ax = plotting.show_palette(hlc_map, cell_size=25)
|
||||||
|
fig.savefig(Path(figure_dir, "palette.png"), pad_inches=0)
|
||||||
|
|
||||||
|
fig, ax = plotting.show_palette(hlc_map, show_labels=False)
|
||||||
|
fig.savefig(Path(figure_dir, "palette-bare.png"), pad_inches=0)
|
||||||
@@ -11,3 +11,6 @@ uv run monobiome palette -n oklch -f toml -o colors/oklch-palette.toml
|
|||||||
|
|
||||||
# generate provided app config
|
# generate provided app config
|
||||||
"$script_dir/generate.sh"
|
"$script_dir/generate.sh"
|
||||||
|
|
||||||
|
# generate release plots
|
||||||
|
uv run "$script_dir/plots.py"
|
||||||
|
|||||||