21/09/08

Utiliser le "color picker" depuis le Terminal

Terminal

Je voulais utiliser le color picker de Mac OS X pour obtenir des couleur hexadécimales… à cela, rien de bien compliqué, en AppleScript, un simple choose color est largement suffisant…

En Python, avec Tkinter, 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 :wink:.

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}.

Color Picker et Terminal de Mac OS X

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 :smile:.

commenter (0)