Skip to content

Instantly share code, notes, and snippets.

@atav32
Forked from MSylvia/convert_itermcolors.py
Last active December 28, 2024 07:12
Show Gist options
  • Save atav32/7c1cfe3e06bd4c87349930995b61c011 to your computer and use it in GitHub Desktop.
Save atav32/7c1cfe3e06bd4c87349930995b61c011 to your computer and use it in GitHub Desktop.
Convert .itermcolors file to html hex & rgb
#!/usr/bin/env python
#
# Convert .itermcolors files to hex colors for html
import sys
import xml.etree.ElementTree as ET
def rgb_to_hex(rgb):
return '#%02x%02x%02x' % rgb
# MAIN
def main():
if len(sys.argv) < 2:
print("usage: ./convert_itermcolors.py file.itermcolors")
exit()
tree = ET.parse(sys.argv[1])
root = tree.getroot()
keys = root.findall("./dict/key")
dicts = root.findall("./dict/dict")
for i in range(len(keys)):
r = int(float(dicts[i][1].text) * 255.0)
g = int(float(dicts[i][3].text) * 255.0)
b = int(float(dicts[i][5].text) * 255.0)
print(rgb_to_hex((r, g, b)) + " rgb({}, {}, {})".format(r, g, b) + " //" + keys[i].text)
if __name__ == '__main__':
main()
$> ./convert_itermcolors.py seoul256.itermcolors
#4e4e4e rgb(78, 78, 78) //Ansi 0 Color
#d68787 rgb(214, 135, 135) //Ansi 1 Color
#5f865f rgb(95, 134, 95) //Ansi 2 Color
#d8af5f rgb(216, 175, 95) //Ansi 3 Color
#85add4 rgb(133, 173, 212) //Ansi 4 Color
#d7afaf rgb(215, 175, 175) //Ansi 5 Color
#87afaf rgb(135, 175, 175) //Ansi 6 Color
#d0d0d0 rgb(208, 208, 208) //Ansi 7 Color
#626262 rgb(98, 98, 98) //Ansi 8 Color
#d75f87 rgb(215, 95, 135) //Ansi 9 Color
#87af87 rgb(135, 175, 135) //Ansi 10 Color
#ffd787 rgb(255, 215, 135) //Ansi 11 Color
#add4fb rgb(173, 212, 251) //Ansi 12 Color
#ffafaf rgb(255, 175, 175) //Ansi 13 Color
#87d7d7 rgb(135, 215, 215) //Ansi 14 Color
#e4e4e4 rgb(228, 228, 228) //Ansi 15 Color
#d0d0d0 rgb(208, 208, 208) //Foreground Color
#3a3a3a rgb(58, 58, 58) //Background Color
#e4e4e4 rgb(228, 228, 228) //Bold Color
#d0d0d0 rgb(208, 208, 208) //Cursor Color
#3a3a3a rgb(58, 58, 58) //Cursor Text Color
#d0d0d0 rgb(208, 208, 208) //Selected Text Color
#005f5f rgb(0, 95, 95) //Selection Color
@atav32
Copy link
Author

atav32 commented Feb 26, 2018

@atav32
Copy link
Author

atav32 commented Feb 26, 2018

Seoul256 iTerm theme: beautiful

@jhrr
Copy link

jhrr commented Jan 27, 2021

Thanks! However, it seems the order of components in dicts is non-deterministic so I made the following changes to remove hardcoded indexing and get things more flexible.

for i in range(len(keys)):
    components = ["Red Component", "Green Component", "Blue Component"]
    colours = {}
    for x in range(len(dicts[i])):
        component = dicts[i][x].text
        if component in components:
            value = dicts[i][x + 1].text
            colours[component] = value
    r = int(float(colours["Red Component"]) * 255.0)
    g = int(float(colours["Green Component"]) * 255.0)
    b = int(float(colours["Blue Component"]) * 255.0)

@junhan-z
Copy link

junhan-z commented Aug 3, 2021

The conversion logic is correct.

However, with the number shown in iterm, it is not consistent, for example, Ansi 0 is actually 0x606060 in iTerm preference. Not sure how does iTerm converts 0-1 float to RGB.

@renegadevi
Copy link

I had issues with this code with latest iTerm export of .termcolors file where it would spit out

Traceback (most recent call last):
  File "/Users/renegadevi/./convert_iterm.py", line 33, in <module>
    main()
    ~~~~^^
  File "/Users/renegadevi/./convert_iterm.py", line 27, in main
    b = int(float(dicts[i][5].text) * 255.0)
            ~~~~~^^^^^^^^^^^^^^^^^^
ValueError: could not convert string to float: 'P3'

So I went trough the code and updated it for python3. Now it works.

#!/usr/bin/env python3
#
# Convert .itermcolors files to hex colors for html

import sys
import xml.etree.ElementTree as ET

def rgb_to_hex(rgb):
    return '#{:02x}{:02x}{:02x}'.format(*rgb)

def safe_float(value):
    try:
        return float(value)
    except (ValueError, TypeError):
        return None

# MAIN
def main():

    if len(sys.argv) < 2:
        print("usage: ./convert_itermcolors.py file.itermcolors")
        sys.exit(1)

    tree = ET.parse(sys.argv[1])
    root = tree.getroot()

    keys = root.findall("./dict/key")
    dicts = root.findall("./dict/dict")

    for i in range(len(keys)):
        color_dict = dicts[i]

        # Extract color components
        r_value = None
        g_value = None
        b_value = None

        for j in range(0, len(color_dict), 2):
            key = color_dict[j].text
            value = color_dict[j + 1].text

            if key == "Red Component":
                r_value = safe_float(value)
            elif key == "Green Component":
                g_value = safe_float(value)
            elif key == "Blue Component":
                b_value = safe_float(value)

        if r_value is None or g_value is None or b_value is None:
            print(f"Skipping key '{keys[i].text}' due to invalid color value.")
            continue

        r = int(r_value * 255.0)
        g = int(g_value * 255.0)
        b = int(b_value * 255.0)

        print("{} rgb({}, {}, {}) //{}".format(
            rgb_to_hex((r, g, b)), r, g, b, keys[i].text
        ))

if __name__ == '__main__':
    main()
$ ./convert_iterm.py Downloads/Untitled.itermcolors
#000000 rgb(0, 0, 0) //Ansi 0 Color
#ef766d rgb(239, 118, 109) //Ansi 1 Color
#8cf67a rgb(140, 246, 122) //Ansi 10 Color
#fefb7e rgb(254, 251, 126) //Ansi 11 Color
#9398ff rgb(147, 152, 255) //Ansi 12 Color
#f07ef8 rgb(240, 126, 248) //Ansi 13 Color
#8ef9fd rgb(142, 249, 253) //Ansi 14 Color
#feffff rgb(254, 255, 255) //Ansi 15 Color
#8cf67a rgb(140, 246, 122) //Ansi 2 Color
#fefb7e rgb(254, 251, 126) //Ansi 3 Color
#9498f7 rgb(148, 152, 247) //Ansi 4 Color
#f07ef8 rgb(240, 126, 248) //Ansi 5 Color
#8ef9fd rgb(142, 249, 253) //Ansi 6 Color
#ffffff rgb(255, 255, 255) //Ansi 7 Color
#676767 rgb(103, 103, 103) //Ansi 8 Color
#ef766d rgb(239, 118, 109) //Ansi 9 Color
#1c222a rgb(28, 34, 42) //Background Color
#ec4023 rgb(236, 64, 35) //Badge Color
#feffff rgb(254, 255, 255) //Bold Color
#c7c7c7 rgb(199, 199, 199) //Cursor Color
#beeafc rgb(190, 234, 252) //Cursor Guide Color
#feffff rgb(254, 255, 255) //Cursor Text Color
#eeeeee rgb(238, 238, 238) //Foreground Color
#255ab4 rgb(37, 90, 180) //Link Color
#ffff00 rgb(255, 255, 0) //Match Background Color
#000000 rgb(0, 0, 0) //Selected Text Color
#c6dcfc rgb(198, 220, 252) //Selection Color

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment