#!/bin/bash # omarchy:summary=Generate themed config files from Omarchy templates # omarchy:hidden=true TEMPLATES_DIR="$OMARCHY_PATH/default/themed" USER_TEMPLATES_DIR="$HOME/.config/omarchy/themed" NEXT_THEME_DIR="$HOME/.config/omarchy/current/next-theme" COLORS_FILE="$NEXT_THEME_DIR/colors.toml" declare -A THEME_COLORS # Convert hex color to decimal RGB (e.g., "#1e1e2e" -> "30,30,46") hex_to_rgb() { local hex="${1#\#}" printf "%d,%d,%d" "0x${hex:0:2}" "0x${hex:2:2}" "0x${hex:4:2}" } # Mix two hex colors. Amount may be a fraction (0.30) or percentage (30%). mix_color() { local start="${1#\#}" local end="${2#\#}" local amount="$3" awk -v start="$start" -v end="$end" -v amount="$amount" ' function hex_value(char) { return index("0123456789abcdef", tolower(char)) - 1 } function hex_pair_to_int(hex, idx) { return hex_value(substr(hex, idx, 1)) * 16 + hex_value(substr(hex, idx + 1, 1)) } BEGIN { if (amount ~ /%$/) { sub(/%$/, "", amount) amount = amount / 100 } else { amount += 0 if (amount > 1) amount = amount / 100 } if (amount < 0) amount = 0 if (amount > 1) amount = 1 start_r = hex_pair_to_int(start, 1) start_g = hex_pair_to_int(start, 3) start_b = hex_pair_to_int(start, 5) end_r = hex_pair_to_int(end, 1) end_g = hex_pair_to_int(end, 3) end_b = hex_pair_to_int(end, 5) red = int(start_r * (1 - amount) + end_r * amount + 0.5) green = int(start_g * (1 - amount) + end_g * amount + 0.5) blue = int(start_b * (1 - amount) + end_b * amount + 0.5) printf "#%02x%02x%02x\n", red, green, blue } ' } add_template_value() { local key="$1" local value="$2" local rgb printf 's|{{ %s }}|%s|g\n' "$key" "$value" >>"$sed_script" printf 's|{{ %s_strip }}|%s|g\n' "$key" "${value#\#}" >>"$sed_script" if [[ $value =~ ^#[0-9A-Fa-f]{6}$ ]]; then rgb=$(hex_to_rgb "$value") printf 's|{{ %s_rgb }}|%s|g\n' "$key" "$rgb" >>"$sed_script" fi } add_mix_value() { local token="$1" local content fn start_key end_key amount start end value content="${token#\{\{}" content="${content%\}\}}" read -r fn start_key end_key amount <<<"$content" start="${THEME_COLORS[$start_key]:-}" end="${THEME_COLORS[$end_key]:-}" [[ $start =~ ^#[0-9A-Fa-f]{6}$ && $end =~ ^#[0-9A-Fa-f]{6}$ ]] || return value=$(mix_color "$start" "$end" "$amount") case "$fn" in mix) ;; mix_strip) value="${value#\#}" ;; mix_rgb) value=$(hex_to_rgb "$value") ;; *) return ;; esac printf 's|%s|%s|g\n' "$token" "$value" >>"$sed_script" } add_mix_values() { local tpl token local -A seen=() for tpl in "${template_files[@]}"; do while IFS= read -r token; do [[ -n ${seen[$token]:-} ]] && continue seen[$token]=1 add_mix_value "$token" done < <(grep -hEo '\{\{[[:space:]]*mix(_strip|_rgb)?[[:space:]]+[A-Za-z0-9_]+[[:space:]]+[A-Za-z0-9_]+[[:space:]]+[0-9]+([.][0-9]+)?%?[[:space:]]*\}\}' "$tpl" 2>/dev/null || true) done } # Only generate dynamic templates for themes with a colors.toml definition if [[ -f $COLORS_FILE ]]; then sed_script=$(mktemp) shopt -s nullglob template_files=("$USER_TEMPLATES_DIR"/*.tpl "$TEMPLATES_DIR"/*.tpl) while IFS='=' read -r key value; do key="${key//[\"\' ]/}" # strip quotes and spaces from key [[ $key && $key != \#* ]] || continue # skip empty lines and comments value="${value#*[\"\']}" value="${value%%[\"\']*}" # extract value between quotes (ignores inline comments) THEME_COLORS[$key]="$value" add_template_value "$key" "$value" done <"$COLORS_FILE" add_mix_values # Process user templates first, then built-in templates (user overrides built-in) for tpl in "${template_files[@]}"; do filename=$(basename "$tpl" .tpl) output_path="$NEXT_THEME_DIR/$filename" # Don't overwrite configs already exists in the output directory (copied from theme specific folder) if [[ ! -f $output_path ]]; then sed -f "$sed_script" "$tpl" >"$output_path" fi done rm "$sed_script" fi