How can I split code blocks into a list?

I want to break the contents of a CSS file into blocks of code and insert each block of code into a list using Python 3.5.

So, given this CSS:

h1 {color: #333, background-color: transparent} h2 { font-weight:300 } h3 { font-weight: 200 } 

We can clearly say that it has several styles and / or indent types, which means that CSS needs to be put in order:

 h1 { color: #333,background-color: transparent; } h2 { font-weight: 300; } h3 { font-weight: 200; } 

How can I use Python to read an ordered CSS string and insert each block of code inside it into a Python list as follows:

 styles = [ "h1 {\n color: #333,background-color: transparent;\n}", "h2 {\n font-weight: 300;\n}", "h3 {\n font-weight: 200;\n}" ] 

I would also like to point out that RegExp is actually not my forte, and I'm not quite sure what to use RegEx, but I thought I could use RegExp and [].split(...); to achieve this.

It’s even possible to use RegExp to get rid of the need to pick up a stylesheet before splitting code blocks in it.

NOTE. I checked this question, but unfortunately it didn’t help either.

+5
source share
2 answers

This implementation is done using tinycss , a simple pure python css parser .

This works in untidied css. So far this is legal.

 import tinycss from collections import defaultdict parser = tinycss.make_parser('page3') # use parse_stylesheet_files to read from a file. stylesheet = parser.parse_stylesheet("""h1 {color: #333; background-color: transparent} h2 { font-weight:300 } h3 { font-weight: 200 } h1{ padding: 0px;} """) # Initialize to empty list if key does not exists # This allows to group multiple blocks with same selectors temp = defaultdict(list) for rule in stylesheet.rules: for dec in rule.declarations: temp[rule.selector.as_css()].append((dec.name, dec.value.as_css())) print(temp) 

Output:

 defaultdict(<class 'list'>, {'h1': [('color', '#333'), ('background-color', 'transparent'), ('padding', '0px')], 'h2': [('font-weight', '300')], 'h3': [('font-weight', '200')]}) 

See how different blocks of h1 got into one list. I'm not very good at CSS intricacies, but it's easy to prevent this.

This is much more flexible since it covers the edges of EVERYTHING , works with selectors, CSS2 and CSS3, unlike a regular expression solution.

Please note: I have enclosed all the words in the dictionary, but you can easily specify it as a list. Let me know if you want something with clean lists, but it should be relatively trivial if you understand what I'm doing.

+3
source

You can achieve this by simply reading and replacing the file:

 styles = [] with open('file.css') as file: style = [] for line in file.readlines(): # If line is empty if not line.strip(): # If a block is non-empty if style: styles.append("".join(style)) style = [] else: # Add to the current block style.append(line) styles.append("".join(style)) 

Output:

 >>> for s in styles: s h1 {\n color: #333,background-color: transparent;\n}\n h2 {\n font-weight: 300;\n}\n h3 {\n font-weight: 200;\n}\n 
+1
source

All Articles