Create the basic palette
- ID
aad50ee- date
2025-11-27 03:55:19+00:00- author
Alex Chan <alex@alexwlchan.net>- parent
0b2d5d6- message
Create the basic palette- changed files
Changed files
.github/workflows/test.yml (709) → .github/workflows/test.yml (758)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index a09eede..f5d1a61 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -39,3 +39,6 @@ jobs:
- name: Check types
run: mypy scripts/*.py --strict
+
+ - name: Run tests
+ run: pytest scripts
css/syntax_highlighting.1c4c93a.css (3311) → css/syntax_highlighting.94fa872.css (3366)
diff --git a/css/syntax_highlighting.1c4c93a.css b/css/syntax_highlighting.94fa872.css
similarity index 89%
rename from css/syntax_highlighting.1c4c93a.css
rename to css/syntax_highlighting.94fa872.css
index c2afd1a..3e9e576 100644
--- a/css/syntax_highlighting.1c4c93a.css
+++ b/css/syntax_highlighting.94fa872.css
@@ -1,25 +1,26 @@
/* Syntax highlighting styles. */
pre {
- --red: var(--default-primary-color-light);
- --green: #1bad0e;
- --blue: #115bda;
- --magenta: #c311d0;
- --yellow: #c8a711;
+ --red: var(--default-primary-color-light);
+ --green: #1bad0e;
+ --blue: #115bda;
+ --magenta: #c311d0;
+ --yellow: #c8a711;
+ --highlight: #ffeb12b3;
--comments: var(--red);
--literals: var(--magenta);
--strings: var(--green);
--names: var(--blue);
--punctuation: var(--accent-grey);
- --mark: #ffeb12b3;
+ --mark: var(--highlight);
@media (prefers-color-scheme: dark) {
- --red: var(--default-primary-color-dark);
- --green: #5ff042;
- --blue: #40c3ff;
- --magenta: #ff42fc;
- --yellow: #fffc42;
- --mark: #fffc42cc;
+ --red: var(--default-primary-color-dark);
+ --green: #5ff042;
+ --blue: #40c3ff;
+ --magenta: #ff42fc;
+ --yellow: #fffc42;
+ --highlight: #fffc42cc;
}
/* Comment, Comment.{Hash, Multiline, Single, Special} */
dev_requirements.in (10) → dev_requirements.in (17)
diff --git a/dev_requirements.in b/dev_requirements.in
index 8881953..daf7d81 100644
--- a/dev_requirements.in
+++ b/dev_requirements.in
@@ -1,2 +1,3 @@
mypy
+pytest
ruff
dev_requirements.txt (341) → dev_requirements.txt (520)
diff --git a/dev_requirements.txt b/dev_requirements.txt
index d5b2b08..f2b9f6c 100644
--- a/dev_requirements.txt
+++ b/dev_requirements.txt
@@ -1,11 +1,21 @@
# This file was autogenerated by uv via the following command:
# uv pip compile dev_requirements.in --output-file dev_requirements.txt
+iniconfig==2.3.0
+ # via pytest
mypy==1.18.2
# via -r dev_requirements.in
mypy-extensions==1.1.0
# via mypy
+packaging==25.0
+ # via pytest
pathspec==0.12.1
# via mypy
+pluggy==1.6.0
+ # via pytest
+pygments==2.19.2
+ # via pytest
+pytest==9.0.1
+ # via -r dev_requirements.in
ruff==0.14.6
# via -r dev_requirements.in
typing-extensions==4.15.0
palette.json (0) → palette.json (362)
diff --git a/palette.json b/palette.json
new file mode 100644
index 0000000..6b7693e
--- /dev/null
+++ b/palette.json
@@ -0,0 +1,19 @@
+{
+ "id": "2477498-94fa872",
+ "light": {
+ "red": "#d01c11",
+ "green": "#1bad0e",
+ "blue": "#115bda",
+ "magenta": "#c311d0",
+ "yellow": "#c8a711",
+ "highlight": "#ffeb12b3"
+ },
+ "dark": {
+ "red": "#f45858",
+ "green": "#5ff042",
+ "blue": "#40c3ff",
+ "magenta": "#ff42fc",
+ "yellow": "#fffc42",
+ "highlight": "#fffc42cc"
+ }
+}
\ No newline at end of file
scripts/test_vendor_css_files.py (0) → scripts/test_vendor_css_files.py (572)
diff --git a/scripts/test_vendor_css_files.py b/scripts/test_vendor_css_files.py
new file mode 100644
index 0000000..6f73e54
--- /dev/null
+++ b/scripts/test_vendor_css_files.py
@@ -0,0 +1,21 @@
+import pytest
+
+from vendor_css_files import get_colour_variable
+
+
+@pytest.mark.parametrize(
+ "css, name, colour",
+ [
+ # Simplest case
+ ("--red: #ff0000;", "red", "#ff0000"),
+ # Variable whitespace between varname and hex string
+ ("--red: #ff0000;", "red", "#ff0000"),
+ # Alpha channel
+ ("--red: #ff0000ff;", "red", "#ff0000ff"),
+ ],
+)
+def test_get_colour_variable(css: str, name: str, colour: str) -> None:
+ """
+ Extract colour variables from CSS.
+ """
+ assert get_colour_variable(css, name=name) == colour
scripts/vendor_css_files.py (1999) → scripts/vendor_css_files.py (3379)
diff --git a/scripts/vendor_css_files.py b/scripts/vendor_css_files.py
index cc26aae..5a4669e 100755
--- a/scripts/vendor_css_files.py
+++ b/scripts/vendor_css_files.py
@@ -5,11 +5,14 @@ create a `palette.json` in the root of the repo.
"""
import glob
+import json
from pathlib import Path
import re
import shutil
import subprocess
+from palette import Colours, Palette
+
def get_alexwlchan_net_css(css_name: str) -> tuple[str, str]:
"""
@@ -34,7 +37,7 @@ def get_alexwlchan_net_css(css_name: str) -> tuple[str, str]:
# If we don't have a vendored copy of the file in this repo, delete
# any previously-vendored copies then copy in the new version.
if not vendor_path.exists():
- for f in glob.glob("syntax_highlighting.*.scss"):
+ for f in glob.glob(f"css/{css_path.stem}.*"):
Path(f).unlink()
shutil.copyfile(css_path, vendor_path)
@@ -46,8 +49,17 @@ def get_colour_variable(css: str, *, name: str) -> str:
"""
Extracts a CSS variable from a snippet of CSS.
"""
- m = re.search(f"--{name}:" + r"\s+(?P<colour>#[0-9a-f]{6}([0-9a-f]{2})?);", css)
- assert m is not None
+ # Example matches:
+ #
+ # --red: #ff0000;
+ # --red: #ff0000;
+ # --red: #ff0000ff;
+ #
+ m = re.search(f"--{name}:" + r"\s*(?P<colour>#[0-9a-f]{6}([0-9a-f]{2})?);", css)
+
+ if m is None:
+ raise ValueError(f"cannot find variable --{name} in CSS")
+
return m.group("colour")
@@ -55,10 +67,34 @@ if __name__ == "__main__":
variable_id, variable_css = get_alexwlchan_net_css("variables.scss")
syntax_id, syntax_css = get_alexwlchan_net_css("components/syntax_highlighting.css")
- # Get the default primary colour, which is used for my two shades
- # of red.
- light_red = get_colour_variable(variable_css, name="default-primary-color-light")
- dark_red = get_colour_variable(variable_css, name="default-primary-color-dark")
+ light_colours: Colours = {
+ "red": get_colour_variable(variable_css, name="default-primary-color-light"),
+ "green": get_colour_variable(syntax_css, name="green"),
+ "blue": get_colour_variable(syntax_css, name="blue"),
+ "magenta": get_colour_variable(syntax_css, name="magenta"),
+ "yellow": get_colour_variable(syntax_css, name="yellow"),
+ "highlight": get_colour_variable(syntax_css, name="highlight"),
+ }
+
+ # Get the first block of dark theme colours from the syntax highlighting
+ # CSS. This is a bit crude, but it works for now.
+ _, dark_syntax_css = syntax_css.split("@media (prefers-color-scheme: dark) {")
+ dark_colours: Colours = {
+ "red": get_colour_variable(variable_css, name="default-primary-color-dark"),
+ "green": get_colour_variable(dark_syntax_css, name="green"),
+ "blue": get_colour_variable(dark_syntax_css, name="blue"),
+ "magenta": get_colour_variable(dark_syntax_css, name="magenta"),
+ "yellow": get_colour_variable(dark_syntax_css, name="yellow"),
+ "highlight": get_colour_variable(dark_syntax_css, name="highlight"),
+ }
+
+ palette: Palette = {
+ "id": f"{variable_id}-{syntax_id}",
+ "light": light_colours,
+ "dark": dark_colours,
+ }
+
+ with open("palette.json", "w") as out_file:
+ out_file.write(json.dumps(palette, indent=2))
- print(light_red)
- print(dark_red)
+ print(f"Written palette {palette['id']} to palette.json")