0

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

Community
  • 1
  • 1
DevC
  • 7,055
  • 9
  • 39
  • 58
  • 1
    If you use SASS, you could do the conversion from hex to rgb by computation. http://stackoverflow.com/questions/9270844/sass-compass-convert-hex-rgb-or-named-color-to-rgba – JohanVdR Mar 13 '14 at 12:14
  • 2
    @Sigma: But that'd still require processing those 50 files to convert them to using SASS, wouldn't it? – Martijn Pieters Mar 13 '14 at 12:31
  • 5
    Voting to reopen; this is **not** a question asking us to recommend or find a tool, library or off-site resource. It is a 'how would I solve this problem, given 50 files' question. – Martijn Pieters Mar 13 '14 at 12:36
  • This question appears to be off-topic because it doesn't include attempted solutions, why they didn't work as specified in http://stackoverflow.com/help/on-topic – martineau Mar 13 '14 at 14:08
  • 2
    @martineau: see [Should Stack Overflow be awarding "A"s for Effort?](http://meta.stackexchange.com/q/210840); the OP clearly did put in some effort to try and figure out what it would take to do the task. – Martijn Pieters Mar 13 '14 at 14:23
  • @Martijn: Yes, the OP apparently did put some effort into figuring out how to convert hex to rgb colors, but little as far as I can tell into what they're asking about. – martineau Mar 13 '14 at 14:36
  • @martineau: That doesn't make the question off-topic. If you feel it is lacking research effort, you can vote. But the question, as it stands, is entirely on topic for Stack Overflow. – Martijn Pieters Mar 13 '14 at 14:40

3 Answers3

11

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.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • @Martijin Looks great to me, let me give it a test for my files where files have as much as 200 different colors entries in single file – DevC Mar 13 '14 at 12:38
  • typo : rbg instead of rgb – ddelemeny Mar 13 '14 at 13:50
  • worked perfect but there are two corrections it should be "inplace=True" and as @ddelemeny pointed it should rgb.. – DevC Mar 13 '14 at 14:06
  • @MartijnPieters I posted one I am using, may be you can suggest more optimized way to os.walk or other tips. – DevC Mar 14 '14 at 09:26
  • @DevC: I usually rely on the UNIX toolkit instead; it's hard to beat `find` for flexibility and power. `find somedir -name \*.css | xargs python scriptname.py` will do all the directory walking for us, with future options to only handle files changed since a given date, or excluding certain filenames or directories, etc. – Martijn Pieters Mar 14 '14 at 13:15
1

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
Community
  • 1
  • 1
DevC
  • 7,055
  • 9
  • 39
  • 58
0

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)
FUSEN
  • 1
  • 1