3Copy a new set of CSS files from a local checkout of my website, and
4create a `palette.json` in the root of the repo.
9from pathlib import Path
14from palette import BaseColours, BasePalette
17def get_alexwlchan_net_css(css_name: str) -> tuple[str, str]:
19 Get a copy of a CSS file from a local checkout of my website.
21 This returns a tuple: the commit ID and CSS text.
23 repo_path = Path.home() / "repos/alexwlchan.net"
24 css_path = repo_path / "src/_scss" / css_name
26 # Get the commit ID of the last change to this file
27 output = subprocess.check_output(
28 ["git", "rev-list", "-1", "HEAD", "--", str(css_path)],
32 commit_id = output[:7]
34 vendor_path = Path("css") / f"{css_path.stem}.{commit_id}{css_path.suffix}"
35 vendor_path.parent.mkdir(exist_ok=True)
37 # If we don't have a vendored copy of the file in this repo, delete
38 # any previously-vendored copies then copy in the new version.
39 if not vendor_path.exists():
40 for f in glob.glob(f"css/{css_path.stem}.*"):
43 shutil.copyfile(css_path, vendor_path)
45 return commit_id, vendor_path.read_text()
48def get_colour_variable(css: str, *, name: str) -> str:
50 Extract a CSS variable from a snippet of CSS.
58 m = re.search(f"{name}:" + r"\s*(?P<colour>#[0-9a-f]+);", css)
61 raise ValueError(f"cannot find variable --{name} in CSS")
65 # 6- or 8-digit hex colour
66 if len(c) == 7 or len(c) == 9:
69 # 3-digit hex colour, so double each digit
71 return f"#{c[1] * 2}{c[2] * 2}{c[3] * 2}"
73 raise ValueError(f"unrecognised hex string: {c}")
76if __name__ == "__main__":
77 variable_id, variable_css = get_alexwlchan_net_css("variables.scss")
78 syntax_id, syntax_css = get_alexwlchan_net_css("components/syntax_highlighting.css")
80 light_colours: BaseColours = {
81 "background": get_colour_variable(
82 variable_css, name="--background-color-light"
84 "text": get_colour_variable(variable_css, name="--body-text-light"),
85 "accent_grey": get_colour_variable(variable_css, name="--accent-grey-light"),
86 "red": get_colour_variable(variable_css, name="--default-primary-color-light"),
87 "green": get_colour_variable(syntax_css, name="--green"),
88 "blue": get_colour_variable(syntax_css, name="--blue"),
89 "magenta": get_colour_variable(syntax_css, name="--magenta"),
90 "yellow": get_colour_variable(syntax_css, name="--yellow"),
91 "highlight": get_colour_variable(syntax_css, name="--highlight"),
95 # Get the first block of dark theme colours from the syntax highlighting
96 # CSS. This is a bit crude, but it works for now.
97 _, dark_syntax_css = syntax_css.split("@media (prefers-color-scheme: dark) {")
98 dark_colours: BaseColours = {
99 "background": get_colour_variable(variable_css, name="--background-color-dark"),
100 "text": get_colour_variable(variable_css, name="--body-text-dark"),
101 "accent_grey": get_colour_variable(variable_css, name="--accent-grey-dark"),
102 "red": get_colour_variable(variable_css, name="--default-primary-color-dark"),
103 "green": get_colour_variable(dark_syntax_css, name="--green"),
104 "blue": get_colour_variable(dark_syntax_css, name="--blue"),
105 "magenta": get_colour_variable(dark_syntax_css, name="--magenta"),
106 "yellow": get_colour_variable(dark_syntax_css, name="--yellow"),
107 "highlight": get_colour_variable(dark_syntax_css, name="--highlight"),
111 # When I do <mark> highlights on my blog, I keep the text black in
112 # dark mode, but for my themes, use a more muted yellow.
113 if dark_colours["highlight"] == "#fffc42cc":
114 dark_colours["highlight"] = "#fffc4244"
116 raise ValueError(f"Unrecognised dark colour: {dark_colours['highlight']}")
118 palette: BasePalette = {
119 "id": f"{variable_id}-{syntax_id}",
120 "light": light_colours,
121 "dark": dark_colours,
124 with open("palette.json", "w") as out_file:
125 out_file.write(json.dumps(palette, indent=2))
127 print(f"Written palette {palette['id']} to palette.json")