Take the 2-minute tour ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

I'm interested in moving color values I've created for OS X Terminal to applications on other platforms, such as Linux. I'm familiar with the usual methods of representing color values like RGB, HSB, L*A*B, HEX, etc. However, the <data> strings used in Terminal settings files are unlike other methods used to define colors. I'd like help understanding this XML <data> type in relation to other color values.

As an example, I used OS X's built-in Color Picker to manually change Terminal's default ANSI scheme with HSB values from Ethan Schoonover's excellent Solarized. I then saved those settings in an XML .plist called Solarized Dark xterm-256color.terminal (The contents of that file may be found here.)

I arbitrarily chose brblack from that file as a single color value for comparison:

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

This looks much different (and more complex) than the simple HSB value 193 100 21 taken from Schoonover's table:

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

Why does the simple value 193 100 21 get converted into a data string 5 lines long? What other information is contained in that string? Finally, and most importantly, how can I convert such a string into simple standard color values that I can use on other platforms?

share|improve this question
add comment

2 Answers 2

up vote 1 down vote accepted

bplist means binary property list, which can be converted to XML with plutil -convert xml1. Inside each plist for a color is another data key for the fractional RGB values.

/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

The output looks like this:

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
share|improve this answer
    
Thank you, this is just what I was looking for. I was thrown a bit by the fractional RGB terminology, but then I realized I could get nominal RGB values by multiplying the fractional values by 255 and rounding (e.g. 0.4769933663 * 255 = 122). I really like your CLI one-liner: You'd make Doug McIlroy and Ken Thompson proud! Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface. Unix Philosophy –  GrowlTiger Aug 16 '13 at 3:11
add comment

You're looking at base64 encoded serialized data.

Base64 + serialized original:

 YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS
AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NOMCAw
LjE2NDUgMC4yMQAQAoAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIU
WE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2Jx
c3V6hY6WmaK0t7wAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAAvg==

Using something like http://www.base64decode.org/, you can see the decoded version:

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

At this point, the interesting part is: NSKeyedArchiver which is the built-in serialization engine in Objective-C, which of course, OSX apps are written in.

As for the question behind your question, of how to convert between this and other standard representations of color: The answer is unfortunately, not easily or reliably.

It's clear that you know how to take an HSB value and generate the encoded data. If you wanted to take the time to reverse engineer how the archiving happens, you'd be able to do it. Not sure what your familiarity with the objective c language is, but you could probably make a simple program that converts between the two. Essentially, probably not worth your time.

share|improve this answer
    
As a footnote, the way to recognize base64 data is to look for really long alphanumeric blocks (yes there are a couple special characters but tend to be rare) and ends in a couple '=', which is the padding character. –  Liyan Chang Aug 13 '13 at 16:27
    
Thank you for your answer. I wasn't really wanting to reverse engineer the process (although that could be an interesting exercise). I just wanted a way to convert the base64 data into a more common color value representation. And your answer did that. It's right there in the second code block. Right after classN: 0 0.1645 0.21. I've learned from @Lauri that these are fractional RGB values, which can be converted to conventional RBG by multiplying them by 255. –  GrowlTiger Aug 16 '13 at 3:20
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.