mirror of
https://github.com/youwen5/liminalOS.git
synced 2025-08-04 11:38:29 -07:00
163 lines
5.5 KiB
Python
163 lines
5.5 KiB
Python
|
import re
|
||
|
import argparse
|
||
|
import sys
|
||
|
|
||
|
|
||
|
def create_themed_css(css_content):
|
||
|
"""
|
||
|
Replaces hardcoded color values in a CSS string with stylix variables.
|
||
|
|
||
|
This function uses a predefined mapping to find and replace color codes (hex and named)
|
||
|
with their corresponding Nix stylix variables (e.g., ${base00}).
|
||
|
|
||
|
Args:
|
||
|
css_content (str): A string containing the source CSS.
|
||
|
|
||
|
Returns:
|
||
|
str: The themed CSS content with stylix variables.
|
||
|
"""
|
||
|
# This dictionary maps stylix variables to a list of colors they should replace.
|
||
|
# It includes various formats (e.g., hex, named colors) for comprehensive matching.
|
||
|
# This structure makes it easy to see which colors are grouped and to extend the theme.
|
||
|
COLOR_MAPPING = {
|
||
|
# Base Backgrounds (Lightest)
|
||
|
"${base00}": [
|
||
|
"#ffffff",
|
||
|
"#fff",
|
||
|
"#fdfdfd",
|
||
|
"#fbfbfb",
|
||
|
"#fcfcfc",
|
||
|
],
|
||
|
# Secondary & Modal Backgrounds
|
||
|
"${base01}": ["#f1f1f1", "#efefef", "#eaebeb", "#e5e5e5"],
|
||
|
# Hover, Active, Disabled States
|
||
|
"${base02}": ["#e7e7e8", "#00000013", "#00000017"],
|
||
|
# Brighter Hover & Light Buttons
|
||
|
"${base03}": [
|
||
|
"#e0e2e2",
|
||
|
"#d9d9d9",
|
||
|
"#e0e0e0",
|
||
|
"#d5d5d5",
|
||
|
"#dbdbdb",
|
||
|
"#0000001c",
|
||
|
"#0000001a",
|
||
|
"#0003",
|
||
|
],
|
||
|
# UI Elements, Medium Grays, Scrollbars
|
||
|
"${base04}": [
|
||
|
"#bbbebe",
|
||
|
"#cbcbcb",
|
||
|
"#d4d4d4",
|
||
|
"#c3c3c3",
|
||
|
"#b6b6b6",
|
||
|
"#dddde0",
|
||
|
"#ababab",
|
||
|
"#0000003d",
|
||
|
"#a6a6a6",
|
||
|
],
|
||
|
# Primary Text & Icons (Darkest)
|
||
|
"${base05}": ["#000", "#000000", "#252525", "#2a2a2a", "#6e6e6e"],
|
||
|
# Secondary Text
|
||
|
"${base06}": [
|
||
|
"#434343",
|
||
|
"#383838",
|
||
|
"#29292a",
|
||
|
"#000000b3",
|
||
|
"#000000ab",
|
||
|
"#0000009a",
|
||
|
],
|
||
|
# "White" Text on Colored Backgrounds
|
||
|
"${base07}": ["#e6e6ed"],
|
||
|
# --- Accent Colors ---
|
||
|
# Red (Errors, Notifications)
|
||
|
"${base08}": ["#fa5656", "#d85959", "#ff5656"],
|
||
|
# Orange
|
||
|
"${base09}": ["#f98f54"],
|
||
|
# Yellow
|
||
|
"${base0A}": ["#d1a70d", "#bc991e", "#e6d165", "#ffd332"],
|
||
|
# Green
|
||
|
"${base0B}": ["#356e56", "#49c47a", "#5deaa6"],
|
||
|
# Cyan (Light)
|
||
|
"${base0C}": ["#d5edeb"],
|
||
|
# Blue / Slate
|
||
|
"${base0D}": ["#96a6af", "#97a1ff"],
|
||
|
# Teal / Primary Accent
|
||
|
"${base0E}": ["#39afa5", "#3cb4aa", "#3bafa5", "#5ecce3", "#8bd4cf"],
|
||
|
# Magenta / Pink
|
||
|
"${base0F}": ["#e860d2"],
|
||
|
}
|
||
|
|
||
|
# Replace the named color 'white' and 'black' first.
|
||
|
css_content = re.sub(r"\bwhite\b", "${base00}", css_content, flags=re.IGNORECASE)
|
||
|
css_content = re.sub(r"\bblack\b", "${base05}", css_content, flags=re.IGNORECASE)
|
||
|
|
||
|
# To handle box-shadows, we replace the hex color part directly.
|
||
|
# We target black shadows specifically, as requested by the stylix spec (`shadow = ${base00}`).
|
||
|
css_content = re.sub(
|
||
|
r"(box-shadow:.*?)#000000([0-9a-fA-F]*)", r"\1${base00}\2", css_content
|
||
|
)
|
||
|
|
||
|
# Iterate through the mapping and replace each color.
|
||
|
for stylix_var, color_list in COLOR_MAPPING.items():
|
||
|
for color in color_list:
|
||
|
try:
|
||
|
# Create a regex pattern for the specific color, ignoring case.
|
||
|
pattern = re.compile(re.escape(color), re.IGNORECASE)
|
||
|
css_content = pattern.sub(stylix_var, css_content)
|
||
|
except re.error as e:
|
||
|
# This error handling is for cases where a color string might form an invalid regex.
|
||
|
print(f"Regex error for color '{color}': {e}", file=sys.stderr)
|
||
|
|
||
|
return css_content
|
||
|
|
||
|
|
||
|
def main():
|
||
|
"""
|
||
|
Main function to parse arguments and run the CSS theming process.
|
||
|
"""
|
||
|
# Set up command-line argument parsing.
|
||
|
parser = argparse.ArgumentParser(
|
||
|
description="Replaces hardcoded colors in a Tidal CSS file with stylix variables.",
|
||
|
formatter_class=argparse.RawTextHelpFormatter,
|
||
|
)
|
||
|
parser.add_argument("input_file", help="The path to the source CSS file.")
|
||
|
parser.add_argument(
|
||
|
"-o",
|
||
|
"--output",
|
||
|
dest="output_file",
|
||
|
help="The path to write the themed CSS file to.\nIf omitted, prints to standard output.",
|
||
|
)
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
# Read the source CSS from the specified input file.
|
||
|
try:
|
||
|
with open(args.input_file, "r", encoding="utf-8") as f:
|
||
|
source_css = f.read()
|
||
|
except FileNotFoundError:
|
||
|
print(f"Error: Input file not found at '{args.input_file}'", file=sys.stderr)
|
||
|
sys.exit(1)
|
||
|
except Exception as e:
|
||
|
print(f"Error reading input file: {e}", file=sys.stderr)
|
||
|
sys.exit(1)
|
||
|
|
||
|
# Process the CSS content to replace colors.
|
||
|
themed_css = create_themed_css(source_css)
|
||
|
|
||
|
# Write the result to the output file or print to the console.
|
||
|
if args.output_file:
|
||
|
try:
|
||
|
with open(args.output_file, "w", encoding="utf-8") as f:
|
||
|
f.write(themed_css)
|
||
|
print(f"Successfully wrote themed CSS to '{args.output_file}'")
|
||
|
except Exception as e:
|
||
|
print(f"Error writing to output file: {e}", file=sys.stderr)
|
||
|
sys.exit(1)
|
||
|
else:
|
||
|
# If no output file is specified, print to standard output.
|
||
|
print(themed_css)
|
||
|
|
||
|
|
||
|
# Execute the main function when the script is run.
|
||
|
if __name__ == "__main__":
|
||
|
main()
|