¿Cómo se representan los esquemas de colores en los archivos de configuración de OS X Terminal.app?

Estoy interesado en mover valores de color que he creado para OS X Terminal a aplicaciones en otras plataformas, como Linux. Estoy familiarizado con los métodos habituales de representación de valores de color como RGB, HSB, L*A*B, HEX, etc. Sin embargo, las <data>cadenas utilizadas en los archivos de configuración de Terminal son diferentes a otros métodos utilizados para definir colores. Me gustaría recibir ayuda para comprender este <data>tipo de XML en relación con otros valores de color.

Como ejemplo, utilicé el Selector de color incorporado de OS X para cambiar manualmente el esquema ANSI predeterminado de Terminal con valores HSB del excelente Solarized de Ethan Schoonover. Luego guardé esa configuración en un XML .plist llamado Solarized Dark xterm-256color.terminal(El contenido de ese archivo se puede encontrar aquí ).

Elegí arbitrariamente brblackde ese archivo como un valor de color único para comparar:

    <key>ANSIBrightBlackColor</key>
    <data>
    YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS
    AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NOMCAw
    LjE2NDUgMC4yMQAQAoAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIU
    WE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2Jx
    c3V6hY6WmaK0t7wAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAAvg==
    </data>

Esto se ve muy diferente (y más complejo) que el simple valor HSB tomado de la tabla193 100 21 de Schoonover :

    SOLARIZED HEX     16/8 TERMCOL  XTERM/HEX   L*A*B      RGB         HSB
    --------- ------- ---- -------  ----------- ---------- ----------- -----------
    base03    #002b36  8/4 brblack  234 #1c1c1c 15 -12 -12   0  43  54 193 100  21
    ...

¿Por qué el valor simple 193 100 21se convierte en una cadena de datos de 5 líneas de largo? ¿Qué otra información está contenida en esa cadena? Finalmente, y lo más importante, ¿cómo puedo convertir una cadena de este tipo en valores de color estándar simples que pueda usar en otras plataformas?

Respuestas (2)

bplistsignifica lista de propiedades binarias, que se puede convertir a XML con plutil -convert xml1. Dentro de cada plist para un color hay otra clave de datos para los valores RGB fraccionarios.

/usr/libexec/PlistBuddy -x -c 'Print "Window Settings":"My Theme"' ~/Library/Preferences/com.apple.Terminal.plist|tr -d '\n\t'|grep -o '[^>]*</key><data>[^<]*'|while read l;do echo ${l%%<*} $(base64 -D<<<${l##*>}|plutil -convert xml1 - -o -|awk '/<data>/{getline;print}'|tr -d '\t'|base64 -D);done

La salida se ve así:

ANSIBlueColor 0.4769933663 0.4769933663 0.9314516129
ANSICyanColor 0.2666655827 0.8165705831 0.8588709677
ANSIGreenColor 0.428833897 0.8508064516 0.490967087
ANSIMagentaColor 0.9072580645 0.4499707336 0.9072580645
ANSIRedColor 0.9072580645 0.508503512 0.508503512
ANSIYellowColor 0.9072580645 0.9072580645 0.3914379553
CursorColor 0.9998760223 0.999984026 0.999786377
SelectionColor 0.3899414837 0.4639441073 0.5917825699
TextBoldColor 0.9441435337 0.4102420509 0.427282244
TextColor 1 0.99997437 0.9999912977
Gracias, esto es justo lo que estaba buscando. Me desconcertó un poco la terminología RGB fraccionaria , pero luego me di cuenta de que podía obtener valores RGB nominales multiplicando los valores fraccionarios por 255 y redondeando (por ejemplo, 0,4769933663 * 255 = 122). Realmente me gusta su línea de CLI: ¡haría que Doug McIlroy y Ken Thompson se sintieran orgullosos! Escriba programas que hagan una cosa y la hagan bien. Escribir programas para trabajar juntos. Escriba programas para manejar flujos de texto, porque esa es una interfaz universal. Filosofía Unix
¡Gracias! Esto puede generar hexadecimal con un awk adicional:/usr/libexec/PlistBuddy -x -c 'Print "Window Settings":"Theme Name"' ~/Library/Preferences/com.apple.Terminal.plist|tr -d '\n\t'|grep -o '[^>]*</key><data>[^<]*'|while read l;do echo ${l%%<*} $(base64 -D<<<${l##*>}|plutil -convert xml1 - -o -|awk '/<data>/{getline;print $1}'|tr -d '\t'|base64 -D| awk '{printf "#%02X%02X%02X", $1*256, $2*256, $3*256}');done

Está viendo datos serializados codificados en base64.

Base64 + original serializado:

 YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS
AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NOMCAw
LjE2NDUgMC4yMQAQAoAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIU
WE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2Jx
c3V6hY6WmaK0t7wAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAAvg==

Usando algo como http://www.base64decode.org/ , puede ver la versión decodificada:

bplist00X$versionX$objectsY$archiverT$topU$null    
UNSRGB\NSColorSpaceV$classN0 0.1645 0.21Z$classnameX$classesWNSColorXNSObject_NSKeyedArchiverTroot#-27;AHN[bqsuz

En este punto, la parte interesante es: NSKeyedArchivercuál es el motor de serialización incorporado en Objective-C, en el que, por supuesto, están escritas las aplicaciones OSX.

En cuanto a la pregunta detrás de su pregunta, de cómo convertir entre esta y otras representaciones estándar de color: desafortunadamente, la respuesta no es fácil ni confiable.

Está claro que sabe cómo tomar un valor HSB y generar los datos codificados. Si quisiera tomarse el tiempo para realizar ingeniería inversa sobre cómo ocurre el archivado, podría hacerlo. No estoy seguro de cuál es su familiaridad con el lenguaje Objective C, pero probablemente podría hacer un programa simple que convierta entre los dos. Esencialmente, probablemente no valga la pena su tiempo.

Como nota al pie, la forma de reconocer los datos base64 es buscar bloques alfanuméricos realmente largos (sí, hay un par de caracteres especiales pero tienden a ser raros) y terminan en un par '=', que es el carácter de relleno.
Gracias por su respuesta. Realmente no quería aplicar ingeniería inversa al proceso (aunque podría ser un ejercicio interesante). Solo quería una forma de convertir los datos base64 en una representación de valor de color más común. Y tu respuesta hizo eso. Está justo ahí en el segundo code block.Justo después de classN: 0 0.1645 0.21. Aprendí de @Lauri que estos son valores RGB fraccionarios, que se pueden convertir a RBG convencional multiplicándolos por 255.