import sys
import re
from functools import partial
# CSS hierarchy
split_css = {}
# Conversion patterns
def append(final_css, item, name):
final_css[name] = item[1]
def merge(final_css, item, name):
if (name in split_css):
for j in split_css[name].iteritems():
if (j[0] not in item[1]):
item[1][j[0]] = j[1]
def attr(final_css, item, name, value):
item[1][name] = value
def delattr(final_css, item, name):
if (name in item[1]):
del item[1][name]
skin_conversion = {
# Page
"#contentcontainer": (
partial(append, name="#content"),
),
"#contentarea": (
partial(append, name="#contentarea"),
partial(delattr, name="float"),
),
# Header
"#header": (
partial(append, name="#header"),
),
"#header img": (
partial(append, name="#header #logo"),
partial(attr, name="float", value="left"),
),
"#header .logo": (
partial(append, name="#header #logo"),
partial(attr, name="float", value="left"),
),
"#header h1": (
partial(append, name="#header h1"),
),
# Menu
"#navbar": (
partial(append, name=".main_dnnmenu_bar"),
partial(attr, name="display", value="block"),
),
"#navbar a": (
partial(append, name=".main_dnnmenu_rootitem"),
partial(append, name=".main_dnnmenu_rootitem_selected"),
),
"#navbar a:hover": (
partial(merge, name="#navbar a"),
partial(append, name=".main_dnnmenu_rootitem_hover"),
),
"#navbar div table": (
partial(append, name=".main_dnnmenu_submenu"),
),
".dmenulink": (
partial(append, name=".main_dnnmenu_submenu td"),
),
".dmenulinkover": (
partial(append, name=".main_dnnmenu_itemhover td"),
),
# Footer
"#footer": (
partial(append, name="#footer"),
),
"#footer h1": (
partial(append, name="#footer h1"),
),
# Common stuff
".link": (
partial(append, name="a"),
partial(append, name="a.CommandButton:link"),
),
".link:hover": (
partial(append, name="a:hover"),
partial(append, name="a.CommandButton:hover"),
),
".hr": (
partial(append, name="hr"),
),
".largefont": (
partial(append, name=".Head"),
),
".highlightedfont": (
partial(append, name=".SubHead"),
),
}
container_conversion = {
"BODY.popup": (
partial(append, name=".eipbackimg"),
),
}
# Initialize regexp patterns
re_css_comments = re.compile(r"\/\*.*?\*\/", re.DOTALL)
re_css_pattern = re.compile(r"(.*?)\s*\{(.*?)\}", re.DOTALL)
# Various logic
def compare_styles(s1, s2):
e1 = [j.strip() for j in s1.split(' ')]
e2 = [j.strip() for j in s2.split(' ')]
return e1 == e2
def is_tag(s):
items = s.split(' ')
for i in items:
if (i[0] == '#' or i[0] == '.'):
return False
if ("." in i):
return False
return True
def process_items(conversion, ignoreTags):
final_css = {}
skipped_css = {}
for (k, v) in split_css.iteritems():
if (not ignoreTags and is_tag(k)):
final_css[k] = v
else:
if (k in conversion):
# Inner loop of conversion
for h in conversion[k]:
h(final_css, (k, v))
else:
skipped_css[k] = v
return (final_css, skipped_css)
def flatten_tree(source):
values = {}
for (k, v) in source.iteritems():
value = "\n".join(("\t%s: %s;" % (j[0], j[1]) for j in v.iteritems()))
if (value in values):
values[value].append(k)
else:
values[value] = [k]
final = []
for (k, v) in values.iteritems():
n = ", ".join((j for j in v))
final.append((n, k))
return final
# Entry point
if (len(sys.argv) < 2):
print "Usage: scripy.py <file>"
sys.exit(-1)
f = file(sys.argv[1], "r")
css = f.read()
f.close()
css = re_css_comments.sub('', css)
elements = re_css_pattern.findall(css)
# Split CSS
for e in elements:
names = e[0].split(',')
for i in names:
n = i.strip()
if (n in split_css):
storage = split_css[n]
else:
storage = {}
for j in e[1].split(';'):
v = j.strip()
if (len(v) == 0):
continue
pair = v.split(':')
storage[pair[0].strip()] = pair[1].strip()
split_css[n] = storage
# Process tree
# Skin
final_css, skipped_css = process_items(skin_conversion, False)
final_css[".clear_float"] = { "clear": "both" }
# Container
container_css, skipped_container_css = process_items(container_conversion, True)
container_css[".c_head"] = { "padding": "0", "margin-top": "8px", "text-align": "left" }
container_css[".c_head h1"] = { "margin": "0", "padding": "0", "float": "left" }
container_css[".c_icon"] = { "float": "left" }
container_css[".c_actions"] = { "float": "left" }
container_css[".c_head_title"] = { "margin": "0", "float": "left" }
container_css[".c_title_vis"] = { "margin": "0", "float": "right" }
container_css[".c_content"] = { "clear": "both" }
container_css[".c_content_pane"] = { "padding": "8px 0 0 0", "text-align": "left" }
container_css[".c_footer"] = { "margin-bottom": "20px", "padding": "0", "text-align": "right" }
# Save skin
final = flatten_tree(final_css)
f = file("skin.css", "w")
for j in final:
f.write("%s {\n%s\n}\n\n" % (j[0], j[1]))
f.close()
# Save container
final = flatten_tree(container_css)
f = file("container.css", "w")
for j in final:
f.write("%s {\n%s\n}\n\n" % (j[0], j[1]))
f.close()
# Save skipped classes
final = flatten_tree(skipped_css)
f = file("skipped.css", "w")
for j in final:
f.write("%s {\n%s\n}\n\n" % (j[0], j[1]))
f.close()
print "Done."