Fix auto-generated everforest obsidian theme readability issues (#2752)

* Fix auto-generated everforest obsidian theme

* Update `--text-muted` and `--text-faint` to be readable against
background color

* Add contrast detection and color correction logic

* Remove dedicated Obsidian CSS file

* Add dedicated text color variables to obsidian theme generation

* Replace closest color logic with generated color for code bg in Obsidian

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
This commit is contained in:
Alex Six
2025-10-27 12:50:37 -04:00
committed by GitHub
parent 556e474942
commit d8f97b8d02

View File

@@ -87,6 +87,35 @@ calculate_brightness() {
echo $(((r * 299 + g * 587 + b * 114) / 1000)) echo $(((r * 299 + g * 587 + b * 114) / 1000))
} }
# Calculate approximate contrast ratio between two colors
# Returns ratio scaled by 100 (e.g., 450 = 4.5:1 ratio)
# (this is due to bash not supporting decimal math)
calculate_contrast_ratio() {
local hex1="$1" hex2="$2"
local br1=$(calculate_brightness "$hex1") # 0-255 range
local br2=$(calculate_brightness "$hex2") # 0-255 range
# Ensure br1 is the lighter color (higher brightness)
if [ $br1 -lt $br2 ]; then
local temp=$br1
br1=$br2
br2=$temp
fi
# Approximate contrast ratio scaled by 100
# Add offset to avoid division by zero and approximate WCAG +0.05 behavior
echo $(((br1 + 13) * 100 / (br2 + 13)))
}
# Check if two colors meet minimum contrast threshold
# Usage: meets_contrast_threshold <ratio> <threshold>
# Both ratio and threshold should be scaled by 100 (e.g., 300 = 3:1)
meets_contrast_threshold() {
local ratio="$1" # Ratio scaled by 100 (from calculate_contrast_ratio)
local threshold="$2" # Threshold scaled by 100 (300=3:1, 450=4.5:1, 700=7:1)
[ $ratio -ge $threshold ]
}
# Calculate color distance (euclidean in RGB space) # Calculate color distance (euclidean in RGB space)
color_distance() { color_distance() {
local hex1="$1" local hex1="$1"
@@ -229,38 +258,30 @@ extract_theme_data() {
fi fi
done done
# Sort by distance and get the closest color for code background
local -a closest_to_bg
readarray -t closest_to_bg < <(printf '%s\n' "${bg_distances[@]}" | sort -n | head -1 | cut -d: -f2)
# All background variations use the same as primary background # All background variations use the same as primary background
local bg_primary_alt="$bg_color" local bg_primary_alt="$bg_color"
local bg_secondary="$bg_color" local bg_secondary="$bg_color"
local bg_secondary_alt="$bg_color" local bg_secondary_alt="$bg_color"
# Code block background uses the closest different color # Generate code background color that will contrast with foreground text
local code_bg="${closest_to_bg[0]}" read -r r g b <<<"$(hex_to_rgb "$bg_color")"
if [ $bg_brightness -gt 127 ]; then
# If no different color available, create a subtle variant for code blocks r=$((r - 10))
if [ -z "$code_bg" ]; then g=$((g - 10))
read -r r g b <<<"$(hex_to_rgb "$bg_color")" b=$((b - 10))
if [ $bg_brightness -gt 127 ]; then else
r=$((r - 10)) r=$((r + 15))
g=$((g - 10)) g=$((g + 15))
b=$((b - 10)) b=$((b + 15))
else
r=$((r + 15))
g=$((g + 15))
b=$((b + 15))
fi
[ $r -lt 0 ] && r=0
[ $r -gt 255 ] && r=255
[ $g -lt 0 ] && g=0
[ $g -gt 255 ] && g=255
[ $b -lt 0 ] && b=0
[ $b -gt 255 ] && b=255
code_bg=$(printf "#%02x%02x%02x" "$r" "$g" "$b")
fi fi
[ $r -lt 0 ] && r=0
[ $r -gt 255 ] && r=255
[ $g -lt 0 ] && g=0
[ $g -gt 255 ] && g=255
[ $b -lt 0 ] && b=0
[ $b -gt 255 ] && b=255
code_bg=$(printf "#%02x%02x%02x" "$r" "$g" "$b")
# Find closest color to foreground for code block text # Find closest color to foreground for code block text
local code_fg="" local code_fg=""
@@ -345,6 +366,22 @@ extract_theme_data() {
border_color=$(printf "#%02x%02x%02x" "$r" "$g" "$b") border_color=$(printf "#%02x%02x%02x" "$r" "$g" "$b")
fi fi
# Set text colors for muted/faint based on contrast
local text_muted_color="$border_color"
local text_faint_color="$border_color"
# Validate border color contrast against background
# Represents a 3:1 WCAG contrast ratio
local ideal_contrast_ratio=300
local border_contrast=$(calculate_contrast_ratio "$border_color" "$bg_color")
if ! meets_contrast_threshold "$border_contrast" "$ideal_contrast_ratio"; then
# Override text colors for readability, keep border color for visibility
text_muted_color="$fg_color"
text_faint_color="$fg_color"
fi
# Get unique colors array (without bg/fg) sorted by frequency # Get unique colors array (without bg/fg) sorted by frequency
local -a unique_colors local -a unique_colors
readarray -t unique_colors < <(echo "$filtered_data" | sort_colors_by_frequency) readarray -t unique_colors < <(echo "$filtered_data" | sort_colors_by_frequency)
@@ -409,8 +446,8 @@ extract_theme_data() {
--text-mark: ${color_slots[7]}; --text-mark: ${color_slots[7]};
--interactive-accent: ${color_slots[8]}; --interactive-accent: ${color_slots[8]};
--blockquote-border: ${color_slots[9]}; --blockquote-border: ${color_slots[9]};
--text-muted: $border_color; /* Use border color for muted text */ --text-muted: $text_muted_color; /* Use text-specific color for muted text */
--text-faint: $border_color; /* Use border color for faint text */ --text-faint: $text_faint_color; /* Use text-specific color for faint text */
/* Additional mappings */ /* Additional mappings */
--text-accent: var(--interactive-accent); --text-accent: var(--interactive-accent);