21/09/08
Utiliser le "color picker" depuis le Terminal

Je voulais utiliser le color picker de Mac OS X pour obtenir des couleur hexadécimales[1]… à cela, rien de bien compliqué, en AppleScript, un simple choose color[2] est largement suffisant…
En Python, avec Tkinter[3], c'est à peine plus compliqué :
#!/usr/bin/env python # -*- coding: utf-8 -*- import Tkinter as tk from tkColorChooser import askcolor (triple, hexstr) = askcolor() print hexstr
De plus, on obtient directement la valeur hexadécimale ! Sauf que le "Color Picker" n'est pas une fenêtre mais un panneau, et qu'il est alors nécessaire de prendre le focus sur l'icône de Python dans le Dock, puisque il n'y a pas de frame/fenêtre.
Donc, je décidais de me tourner vers Bash, puisque, avec AppleScript et la commande osascript, j'allais attacher le panneau du color picker à la fenêtre d'une application scriptable, en l'occurrence, le Terminal ; même si, alors, il allait être nécessaire de faire les conversions de décimal à hexadécimal et que, a priori, Bash n'est pas le langage de choix pour faire des calculs
.
En effet, dans l'exemple ci-après, la commande choose color retourne, une valeur RGB sous la forme d'une liste AppleScript, {65535, 13107, 13107}.
Ce qui donne, en Bash :
#!/bin/bash # Time-stamp: <2008-09-23 20:40:52 (blogosx.homeunix.org)> version="1.0.2a" # last color used # $1 `temp file` function get_lastcolor () { local tmpfile="$1" local color='0, 0, 0' [[ -e "${tmpfile}" ]] && local color=$(cat "${tmpfile}") echo "$color" } # $1 `default color` function get_color() { local cmd=$(printf "tell application \"Terminal\" to set c to choose color default color {${1}}\nreturn c") local color=$(osascript -e "$cmd" 2> /dev/null) printf "$color" } # $1 `color to convert` function convert_color() { local color="$1" local IFS=',' for i in $color; do local c256=$(bc <<< "${i}/256") local hexa=$(bc <<< "ibase=10;obase=16;${c256}") local c_css="${c_css}${hexa}" done echo $c_css } # parse arguments function parse_args() { eval CUROPT=\$$((OPTIND)) while getopts "vh-:" opt 2> /dev/null; do if [ $opt = "-" ] ; then case $OPTARG in help ) opt='h' ;; version ) opt='v' ;; nocopy ) opt_copy=0 opt='' ;; css ) opt_css=1 opt='' ;; * ) printf "Invalid option…\n" >&2 exit 1 ;; esac fi case $opt in h ) printf "Usage: $(str_bin) [OPTIONS]\n$(usage 0)\n" >&1 exit 0 ;; v ) printf "$(str_bin), version ${version}\n" >&1 exit 0 ;; ? ) printf "Invalid option…\n" >&2 exit 1 ;; esac done } # display usage (--help) # exit $1 function usage() { cat << EOF Options: [--nocopy] [--css] [--version] [--help] EOF exit $1 } function str_bin () { local dir=$(dirname "$0") local bin=$(echo "${0}" | awk -F "${dir}/" '{print $2}') printf "${bin}" } # main function function main() { local hash=$(md5 "$0" | awk -F " = " '{print $2}') local tmpfile="/tmp/$(str_bin)_${hash}" local color=$(get_lastcolor "$tmpfile") local flag=1 opt_copy=1 opt_css=0 parse_args "${@}" while [[ "$flag" -gt 0 ]]; do local color=$(get_color "$color") if [[ -n "$color" ]]; then if [[ -n "$hash" && -n "$(str_bin)" ]]; then echo "$color" > "$tmpfile" fi local color_out=$(convert_color "$color") if [[ "$opt_css" -gt 0 ]]; then color_out="#${color_out}" fi if [[ "$opt_copy" -gt 0 ]]; then printf "$color_out" | pbcopy && { printf "copied to clipboard: ${color_out}\n" >&1 } else printf "${color_out}\n" >&1 fi local flag=1 else local flag=0 fi done; exit 0 } main "${@}" # Local Variables: # mode: Shell-script # coding: mule-utf-8 # End:
Le script "se souvient", au cours d'une même session, de la dernière couleur utilisée, grâce à un fichier temporaire. Le color picker reste affiché jusqu'à ce qu'on le quitte en utilisant le bouton Annuler. Par défaut, chaque couleur sélectionnée est copiée dans le presse-papier en utilisant le bouton OK. Le color picker est attaché aux fenêtres du Terminal.
Voilà, c'est tout
.