Skip to content

Instantly share code, notes, and snippets.

@Inviz
Created January 14, 2011 14:09
Show Gist options
  • Save Inviz/779642 to your computer and use it in GitHub Desktop.
Save Inviz/779642 to your computer and use it in GitHub Desktop.
JSON.stringify(SheetParser.CSS.translate("a a(b), 1px 3em, gradient(from(rgba(1, 1, 1, 3)), to(#ccc)"))
"[["a",{"a":"b"}],[{"unit":"px","number":"1"},{"unit":"em","number":"3"}],"gradient",{"from":{"rgba":["1","1","1","3"]}},{"to":"#ccc"}]"
// Stuff below generates this regex:
// /(-?\d+(?:\.\d*)?)(em|px|%|fr)?|(top|left|bottom|right|center)|(#[0-9a-f]{3,6})|([-a-zA-Z0-9]+)\(((?:[^()]|\((?:[^()]|\((?:[^()]|\((?:[^()]|\([^()]*\))*\))*\))*\)))\)|(\s*,\s*)|(\s+)|((?:"(?:[^"]|\\")*"|'(?:[^']|\\')*'))|((?:[-a-zA-Z0-9]+))/gm
;(CSS.integer = x('-?\\d+'))
;(CSS.phloat = x('-?\\d+(?:\\.\\d*)?'))
;(CSS.number = x([CSS.phloat], "number"))
;(CSS.unit = x(['em|px|%|fr'], 'unit'))
;(CSS.length = x([CSS.number, CSS.unit, "?"]))
;(CSS.direction = x(['top|left|bottom|right|center'], 'direction'))
;(CSS.position = x([CSS.length, OR, CSS.direction]), 'position')
;(CSS.func = x("([-a-zA-Z0-9]+)\\((" + rRound + "*)\\)"))
.names = [ 'func', '_arguments'];
;(CSS.hex = x(["#[0-9a-f]{3,6}"], 'hex'));
CSS.comma = x(["\\s*,\\s*"], 'comma');
CSS.whitespace = x(["\\s+"], 'whitespace');
CSS.text = x([CSS.string, OR, "(?:[-a-zA-Z0-9]+)"], "text")
CSS.value = x
(
[ x(CSS.hex)
, OR
, x(CSS.func),
, OR
, x(CSS.position)
, OR
, x(CSS.comma)
, OR
, x(CSS.whitespace)
, OR
, x(CSS.text)
]
)
CSS.translate = function(value) {
var found, whitespace, result = [], scope = result;
var regex = x(CSS.value);
var names = regex.names;
while (found = regex.exec(value)) {
var length = result.length;
if (found[names.comma] && !length) continue //throw "comma in the beginning?"
var number = found[names.number]
if (number) {
var unit = found[names.unit]
scope.push(unit ? {unit: unit, number: number} : number)
continue;
}
if (found[names.whitespace] && !whitespace) {
whitespace = true;
scope = [result[length - 1]];
result.splice(length - 1, 1, scope)
continue;
}
if (found[names.comma]) {
whitespace = false;
scope = result;
continue;
}
var func = found[names.func];
if (func) {
var obj = {};
obj[func] = CSS.translate(found[names._arguments])
scope.push(obj)
continue
}
var hex = found[names.hex];
if (hex) {
scope.push(hex);
continue
}
var text = found[names.text];
if (text) {
scope.push(text);
continue
}
}
return result.length == 1 ? result[0] : result;
}
@subtleGradient
Copy link

You might should make something in the main file like defineShortcut and then in a separate file actually define all the default shortcuts in various versions of CSS. E.g. background for background-color, background-image, etc...

This is because the parser itself has applications outside of styling and I wouldn't want to include extra unrelated stuff in the main file.

@subtleGradient
Copy link

One tricky thing to support would be getting the values back out of order. E.g. border: 1px solid blue; vs border: blue 1ps solid

@Inviz
Copy link
Author

Inviz commented Jan 15, 2011

Current parser keeps the order of properties, so it is probably not that hard.

@Inviz
Copy link
Author

Inviz commented Jan 15, 2011

Actually, I see what you mean now.

For some properties the order of arguments defined, for some not. It is in official spec, but it's not that easy to find reasonable syntax to have those rules in javascript accessible and readable form. I'm thinking about it.

@Inviz
Copy link
Author

Inviz commented Jan 15, 2011

= linear-gradient(
[
[ [top | bottom] || [left | right] ]
||

,]?
[, ]+
);

That's what they have in spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment