0

I obtain some CSS and store it in a var, but i am trying to use regexes to parse classes. Thats the easy part, but it seems that i have issues with the regex to scrape contents between the braces to store.

My attempt is at: http://jsfiddle.net/2qaCY/

All i want is to iteratively loop through the classes and scrape the contents between the braces.

code on fiddle:

var css = ".Winning{color: #24CCFF;background-color: #FF8091;}.Losing{color: #2EFFCE;background-color: #DB4DFF;}.crayons{font-family: papyrus;font-size: 32pt;}";

var reg = /\.[a-zA-Z0-9]*\{/ig;
var matches = css.match(reg);
for (var m in matches) {
    var sClass = matches[m].substr(0, matches[m].length - 1);
    $("body").append(sClass + "<br />");
    var c = new RegExp("\\." + sClass + "[\\n\\s]*\{[\\s\\n.]*\}", "ig");
    var out = c.exec(css);
    $("body").append(out);
    $("body").append("<br /><br />");
}
Fallenreaper
  • 10,222
  • 12
  • 66
  • 129
  • I would instead convert it into an object then parse the object. You would just need to place a comma after every `}`, a `:` before every `{`, replace every `;` with a comma, and then wrap every key and value in double quotes while escaping inner double quotes. From that object, you can create an array of objects, sort them by type/name, and then output them however you like. Might have to do more cleaning up in the first part to make it work – Kevin B Sep 12 '13 at 18:34
  • MMM, i actually think i like that response. Definitely thinking outside the box. Im just thinking of how i would implement it all instead of just the pseudocode. – Fallenreaper Sep 12 '13 at 18:36
  • Take a look at this question regarding parsing CSS with javascript. http://stackoverflow.com/questions/3326494/parsing-css-in-javascript-jquery – Vlad Sep 12 '13 at 18:40
  • Here's a rough sample: http://jsfiddle.net/2qaCY/8/ I did it in many steps so i could inspect the result as i worked through it. – Kevin B Sep 12 '13 at 18:44
  • Obviously that would only work if you keep your classnames and id's simple. Once you start making classes/id's with : or using :: selectors or : selectors things may get hairy. Updated to possibly take those issues into account: http://jsfiddle.net/2qaCY/9/ – Kevin B Sep 12 '13 at 18:49
  • The thing im making is allowing the user define classes, but as you can tell it opens it up to a lot of issues and cases. If they break it, it is their own fault. So says the guidelines. – Fallenreaper Sep 12 '13 at 18:52
  • @KevinB when i opened your example: /9, it was giving me an error for the cssOut = JSON.parse(cssOut); – Fallenreaper Sep 12 '13 at 18:55
  • 1
    @Fallenreaper yeah, i posted without testing. Here it is fixed: http://jsfiddle.net/2qaCY/10/ The only thing i see at the moment that this won't work on is `:` in the css selector, so no psudoelements or psudoselectors. – Kevin B Sep 12 '13 at 18:55
  • not bad. Not bad at all.. :-D – Fallenreaper Sep 12 '13 at 18:57
  • Ofcourse, you could just paste the text into style tags in an iframe and let the browser parse it, then get the stylesheet object. Haven't messed with that much so i don't have any samples of it. – Kevin B Sep 12 '13 at 18:59

1 Answers1

1

Ok, so the following example stores the class in an array and the whole thing in a map where the key is the class and the contents are the value for that key.

If you want a solution with regexp it's 10 more minutes but this is what you want I believe.

http://jsfiddle.net/2qaCY/11/

var css = ".Winning{color: #24CCFF;background-color: #FF8091;}.Losing{color: #2EFFCE;background-color: #DB4DFF;}.crayons{font-family: papyrus;font-size: 32pt;}";

var reg = /\.[a-zA-Z0-9]*\{[a-zA-Z0-9:\- #;]+\}/ig;
var matches = css.match(reg);
var classes = []
var classMap = {}

matches.map(function(item) {
    var cl = (item.split("{")[0])
    classes.push(cl)
    classMap[cl] = item.split("{")[1].split("}")[0]            
})

// All the classes in an array
console.log(classes);
console.log(classMap);
bitoiu
  • 6,893
  • 5
  • 38
  • 60
  • in your example, you end up printing out sClass, which is the entire line. it does not actually break it into 2 objects. BUT from that point, you could break it into 2 pieces far easier with (HOPEFULLY) regexes /\..*[\n\s]*{/ minus end charand /\{[\n.]*\}/ minus first and end character – Fallenreaper Sep 12 '13 at 18:45
  • Tell me line by line which HTML you want in the end and I'll fix it. It was already putting the class in the HTML, so not sure what is the goal if not printing the whole thing? – bitoiu Sep 12 '13 at 18:47
  • i am going to want the class: Winner, Losing, crayons in an array, and the contents of the braces for each class in a hash. so: {Winning:"color: #24CCFF;background-color: #FF8091;", Losing:"color: #2EFFCE;background-color: #DB4DFF;", crayons: "font-family: papyrus;font-size: 32pt;"} – Fallenreaper Sep 12 '13 at 18:50
  • check my updated code and fiddle. before running it open the chrome/firefox console to see the output of the array and map. – bitoiu Sep 12 '13 at 19:01
  • Wow. i really like that, and i forgot entirely about .map() – Fallenreaper Sep 12 '13 at 19:05
  • better even would be to do that with a reduce ;) – bitoiu Sep 12 '13 at 19:15