DevC
DevC

Reputation: 7423

Change all hex colors values to rgb

I have around 50 css files with more than 200 color entries. I need to convert all hex colors values to rgb. Is there any tool which can my task easy else I have to open every css file and do it manually.

for example

color:#ffffff;

should be converted to

color: rgb(255,255,255);

I am comfortable with Python, so if there is something in python which can make my job easier. There is very good python method to do the hex to rgb conversion . But how do I read and replace in css file all the colors values.. for sure they will start with #.

Upvotes: 0

Views: 2658

Answers (3)

FUSEN
FUSEN

Reputation: 1

For people who want easier control and facing the same issue

pip install pyopt-tools

you can use Martijin's regex to find colors and replace with this method

from pyopt_tools.colors import Color 

c = Color("#ffffff")
converted = c.to_rgb()
print(converted)

output:

(255, 255, 255)

Upvotes: 0

DevC
DevC

Reputation: 7423

Martijin's solution is great. I was not aware about fileinput module so earlier I was reading every file and transferring the replacement in temp file and removing the old one, but fileinput made it very smooth and faster. Here is my script which expects a folder as argument from current directory and will traverse and find all the css files and replace the colors. Error handling can be improved more.

import fileinput
import os
import sys
import re

_hex_colour = re.compile(r'#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b')
_current_path = os.getcwd() #folder arg should be from current working directory 
_source_dir=os.path.join(_current_path,sys.argv[1]) #absolute path
cssfiles = []

def replace(match):
    value = match.group(1)
    if len(value) == 3:  # short group
        value = [str(int(c + c, 16)) for c in value]
    else:
        value = [str(int(c1 + c2, 16)) for c1, c2 in zip(value[::2], value[1::2])]
    return 'rgb({})'.format(', '.join(value))

for dirpath, dirnames, filenames in os.walk (_source_dir):
    for file in filenames:
        if file.endswith(".css"):
            cssfiles.append(os.path.join(dirpath,file))


try:
    for line in fileinput.input(cssfiles,inplace=True):
        line = _hex_colour.sub(replace, line)
        sys.stdout.write(line)
    print '%s files have been changed'%(len(cssfiles))

except Exception, e:
    print "Error: %s"%(e) #if something goes wrong

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1122382

Use the fileinput module to create a script that can handle 1 or more files, replacing lines as needed.

Use regular expressions to find your hex RGB value, and take into account that there are two formats; #fff and #ffffff. Replace each format:

import fileinput
import sys
import re

_hex_colour = re.compile(r'#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b')

def replace(match):
    value = match.group(1)
    if len(value) == 3:  # short group
        value = [str(int(c + c, 16)) for c in value]
    else:
        value = [str(int(c1 + c2, 16)) for c1, c2 in zip(value[::2], value[1::2])]
    return 'rgb({})'.format(', '.join(value))

for line in fileinput.input(inplace=True):
    line = _hex_colour.sub(replace, line)
    sys.stdout.write(line)

The regular expression looks for a # followed by either 3 or 6 hexadecimal digits, followed by a word boundary (meaning what follows must not be a character, digit or underscore character); this makes sure we don't accidentally match on a longer hexadecimal value somewhere.

The #hhh (3 digit) patterns are converted by doubling each hex digit; #abc is equivalent to #aabbcc. The hex digits are converted to integers, then to strings for easier formatting, then put into a rgb() string and returned for replacement.

The fileinput module will take filenames from the command line; if you save this as a Python script, then:

python scriptname.py filename1 filename2

will convert both files. Without a filename stdin is used.

Upvotes: 11

Related Questions