Real Parser |
function parser(css) { var stack = [], rules = [], context = rules, state = 'before-selector', buffer = 0, index = 0, rule, char, start;
this.cssText = css; this.rules = rules;
while (char = css.charAt(index++)) { switch(char) { case ' ': case '\t': case '\r': case '\n': case '\f': if (state === 'selector') { buffer++; } break; case '{': if (state !== 'selector') { break; } start = index - buffer - 1; rule = new Rule(css, css.slice(start, index - 1).trim(), start, index); context.push(rule); stack.push(context); context = rule.nested; state = 'before-selector' buffer = 0; break; case ';': if (state !== 'selector') { break; } state = 'before-selector'; buffer = 0; break; case '}': if (state !== 'before-selector') { break; } context = stack.pop(); rule = context[context.length - 1]; if (rule) { rule.end = index; rule.declarationEnd = index - 1; } else { console.log('Closing unopened rule'); } state = "before-selector"; buffer = 0; break; default: if (state === 'before-selector') { state = 'selector'; } buffer++; break; } } // Pop remaining while (stack.length) { context = stack.pop(); rule = context[context.length - 1]; rule.end = rule.declarationEnd = css.length; console.log("Unclosed rule: '" + rule.selector + "'"); }
return rules; }
var result = parser("h1 {\n color: red;\n }\n\n .some-class {\n color: #ff0;\n background: #f00;\n\n .nested {\n color: blue;\n\n .another {\n background: pink;\n }\n }\n }");
|
pending… |
Regex Parser |
function parser(css) { var length = css.length, stack = [], context, nested, match, open, close, rule, rules; this.cssText = css; this.rules = rules = context = [];
while (css) { open = css.indexOf('{'); close = css.indexOf('}'); if (open >= 0 && (close == -1 || open < close) && (match = css.match(openRe))) { css = css.slice(open + 1); rule = new Rule(this.cssText, match[2].trim(), length - css.length - match[1].length, length - css.length); context.push(rule); stack.push(context); context = rule.nested; } else if (close >= 0 && (open == -1 || close < open) && (match = css.match(closeRe))) { css = css.slice(close + match.length); context = stack.pop(); rule = context[context.length - 1]; if (rule) { rule.end = length - css.length; rule.declarationEnd = rule.end - match.length; } else { console.log('Closing unopened rule'); } } else { css = null; } }
// Pop remaining while (stack.length) { context = stack.pop(); rule = context[context.length - 1]; rule.end = rule.declarationEnd = length; console.log("Unclosed rule: '" + rule.selector + "'"); }
return rules; }
var result = parser("h1 {\n color: red;\n }\n\n .some-class {\n color: #ff0;\n background: #f00;\n\n .nested {\n color: blue;\n\n .another {\n background: pink;\n }\n }\n }");
|
pending… |
0 comments