#!/usr/bin/env bash # set -vx printhelp() { cat <&2 exit 2 } dependencycheck() { local dep missingdependencies=0 for dep in "$@"; do if ! command -v "$dep" &>/dev/null; then error "dependency not met: $dep" fi done if [[ $missingdependencies -gt 0 ]]; then exit 1 fi } hex_to_rgb() { local a # null command ':' removes all leading hashtag characters : "${1/\#/}" # if hex value is 8 characters if ((${#_} == 8)); then # convert characters to hex (see credits at bottom) ((r = 16#${_:0:2}, g = 16#${_:2:2}, b = 16#${_:4:2}, a = 16#${_:6:2})) # simple calc for alpha channel a=$(echo "scale=2; $a / 255" | bc) # else if hex value is 6 characters (no alpha channel) elif ((${#_} == 6)); then ((r = 16#${_:0:2}, g = 16#${_:2:2}, b = 16#${_:4:2})) a=1.0 # else if hex value is 3 characters (minimal hex value provided) elif ((${#_} == 3)); then # if the first character still has a hashtag in it... if [[ ${1:0:1} != "#" ]]; then color="#$1" else color="$1" fi # grab out each passed value r="$(echo "$color" | cut -c2)" g="$(echo "$color" | cut -c3)" b="$(echo "$color" | cut -c4)" # and convert them to hexadecimal r=$(printf "%d" 0x$r$r) g=$(printf "%d" 0x$g$g) b=$(printf "%d" 0x$b$b) # ((r = 16#${_:0:1}, g = 16#${_:1:1}, b = 16#${_:2:1})) a=1.0 else error "$1 is not a recognized hex color code." fi printf "%s\n" "rgba($r, $g, $b, $a)" } # parse_rgb() takes rgb string to pass to rgb_to_hex() parse_rgb() { local regex='^rgb[a]?[(][0-9]{1,3}, [0-9]{1,3}, [0-9]{1,3}[)]$|^rgb[a]?[(][0-9]{1,3}, [0-9]{1,3}, [0-9]{1,3}, [0-1]?.[0-9][0-9]?[)]$' if [[ $2 =~ $regex ]]; then local numbers numbers=$(echo "$2" | sed -n 's/.*\(([^()]*)\).*/\1/p' | sed 's/[()]//g' | sed 's/,\s/ /g') read -r -a rgb <<< "$numbers" rgb_to_hex "${rgb[$"0"]}" "${rgb[$"1"]}" "${rgb[$"2"]}" "${rgb[$"3"]}" else error "pattern passed is not valid rgba format" 2 fi } rgb_to_hex() { local a # if a fourth arg is provided (alpha channel) if [[ -n "$4" ]]; then # converts alpha channel to hex (see below) a=$(printf "%02x\n" "$(echo "scale=0; $4*255" | bc)" 2>/dev/null) printf "#%02x%02x%02x%s\n" "$1" "$2" "$3" "$a" else printf "#%02x%02x%02x\n" "$1" "$2" "$3" fi } main() { [[ "$#" -lt 1 ]] && printhelp while getopts ":x:r:?" arg; do case $arg in x) if [[ "$#" -gt 2 ]]; then error "-x only parses one following argument" fi local rgbval clipit rgbval=$(hex_to_rgb "${2:-''}") printf "%s\n" "$rgbval" read -e -r -p "save code to clipboard?(y/n): " clipit if [[ "$clipit" == "yes" || "$clipit" == "y" ]]; then dependencycheck xclip printf "%s" "$rgbval" | xclip -sel clip fi ;; r) local hexval clipit if [[ "$#" -eq 2 ]]; then hexval=$(parse_rgb "$@") printf "%s\n" "$hexval" read -e -r -p "save code to clipboard?(y/n): " clipit if [[ "$clipit" == "yes" || "$clipit" == "y" ]]; then dependencycheck xclip printf "%s" "$hexval" | xclip -sel clip fi else hexval=$(rgb_to_hex "${@:2}") printf "%s\n" "$hexval" read -e -r -p "save code to clipboard?(y/n): " clipit if [[ "$clipit" == "yes" || "$clipit" == "y" ]]; then dependencycheck xclip printf "%s" "$hexval" | xclip -sel clip fi fi ;; ?) printhelp ;; esac done } main "$@" # Credits: # Thanks go out to those who helped: # Akash Mittal, whose article provided the original versions of hex_to_rgb() and rgb_to_hex() taken from # https://akashmittal.com/code-example-convert-hex-color-to-rgb-rgb-to-hex-using-bash-script/ # redditor zeekar who broke down what those functions did line by line: # https://reddit.com/r/bash/comments/zqmvz8/rgbhex_converter_syntax_how_does_this_work/ # redditor DyslexicHobo, who suggested ChatGPT, which I used to finalize the # rgb_to_hex() function. Thank you AI overlords! # https://openai.com/blog/chatgpt/