If you don't know what AST is, first read [article at Wikipedia] (http://en.wikipedia.org/wiki/Abstract_syntax_tree).
In general Gonzales AST looks like this:
['stylesheet',
['atrules', ..],
['s', ' '],
['commentML', 'sample'],
['ruleset',
['selector', ..]],
['block', ..]]
operator / unary — rather artificial division, in addition unary is misnamed. Utilities working with AST may need to handle both types of nodes instead of one.
raw — currently raw contains unparsed progid
IE. In the future it makes
sense to parse that parts in full AST.
Node is a JavaScript array of the following type:
['token type', <- required
<content>] <- optional
Content can be other nodes or CSS source.
In case needInfo
parameter was true
, the node includes info object.
It contains token's index number and token's line number:
[{ ln: ln, tn: tn }, <- info object
'token type', <- required
<content>] <- optional
In alphabetical order.
Mixin's arguments.
Valid only for scss syntax.
Can be any number of:
- string,
- ident,
- vhash,
- variable,
- number,
- declaration,
wraped with braces, mixed with spaces and separated with commas.
(10)
↓
['arguments',
['number', '10']]
@-rule identifier.
@font-face
↓
['atkeyword',
['ident', 'font-face']]
Block @-rule.
Consists of:
- atkeyword (@-rule identifier),
- rule, and
- block.
@test x y {p:v}
↓
['atruleb',
['atkeyword',
['ident', 'test']],
['s', ' '],
['ident', 'x'],
['s', ' '],
['ident', 'y'],
['s', ' '],
['block',
['declaration',
['property',
['ident', 'p']],
['propertyDelim'],
['value',
['ident', 'v']]]]]
@-rule with a ruleset.
Consists of:
- atkeyword (@-rule identifier),
- rule, and
- styles set.
@media x y {s{p:v}}
↓
['atruler',
['atkeyword',
['ident', 'media']],
['atrulerq',
['s', ' '],
['ident', 'x'],
['s', ' '],
['ident', 'y'],
['s', ' ']],
['atrulers',
['ruleset',
['selector',
['simpleselector',
['ident', 's']]],
['block',
['declaration',
['property',
['ident', 'p']],
['propertyDelim'],
['value',
['ident', 'v']]]]]]]
Single-line @-rule.
Consists of:
- atkeyword (@-rule identifier), and
- rule.
@import url('/css/styles.css')
↓
['atrules',
['atkeyword',
['ident', 'import']],
['s', ' '],
['uri',
['string', ''/css/styles.css'']]]
Attribute selector.
[a='b']
↓
['attrib',
['ident', 'a'],
['attrselector', '='],
['string', ''b'']]
Attribute selector operator: =
, ~=
, ^=
, $=
, *=
, |=
.
[a='b']
↓
['attrib',
['ident', 'a'],
['attrselector', '='],
['string', ''b'']]
Part of the style in braces: {...}
.
For *.sass
files — code that will be compiled to a block.
{ color: red }
↓
['block',
['s', ' '],
['declaration',
['property',
['ident', 'color']],
['propertyDelim'],
['value',
['s', ' '],
['ident', 'red'],
['s', ' ']]]]
Braces and their content.
()
(1)
↓
['braces', '(', ')']
['braces', '(', ')',
['number', '1']]
Class.
.abc
↓
['class',
['ident', 'abc']]
Combinator: +
, >
, ~
.
x+y { .. }
↓
['simpleselector',
['ident', 'x'],
['combinator', '+'],
['ident', 'y']]
Multi-line comment.
/* test */
↓
['commentML', ' test ']
Single-line comment. Valid for less, scss and sass.
// comment
↓
['commentSL', ' comment']
Condition. Valid for less, scss and sass.
@if nani == panda
↓
['condition',
['atkeyword',
['ident', 'if']],
['s', ' '],
['ident', 'nani'],
['s', ' '],
['operator', '='],
['operator', '='],
['s', ' '],
['ident', 'panda']]
Property/value pair.
Consists of:
- property,
- propertyDelim and
- value
mixed with spaces and comments.
color: red
↓
['declaration',
['property',
['ident', 'color']],
['propertyDelim'],
['value',
['s', ' '],
['ident', 'red']]]
Declaration delimiter in block: \n
for sass, ;
for other syntaxes.
x {a: b; c: d}
↓
['block',
['declaration',
['property',
['ident', 'a']],
['propertyDelim'],
['value',
['s', ' '],
['ident', 'b']]],
['declDelim'],
['s', ' '],
['declaration',
['property',
['ident', 'c']],
['propertyDelim'],
['value',
['s', ' '],
['ident', 'd']]]]
!default
keyword.
Valid only for scss and syntax.
a: b !default
↓
['declaration',
['property',
['ident', 'a']],
['propertyDelim'],
['value',
['s', ' '],
['ident', 'b'],
['s', ' '],
['default']]]
Simple selector delimiter in selector: ,
.
x,y{ .. }
↓
['selector',
['simpleselector',
['ident', 'x']],
['delim'],
['simpleselector',
['ident', 'y']]]
Number with dimension unit.
10px
↓
['dimension',
['number', '10'],
['ident', 'px']]
Escaped string.
Valid only for less.
~"ms:alwaysHasItsOwnSyntax.For.@{what}()"
↓
['escapedString', '"ms:alwaysHasItsOwnSyntax.For.@{what}()"']]
Node to store IE filter
.
Consists of:
- property (property name),
- filterv (contents), and
- progid (
progid
itself).
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='a.png',sizingMethod='scale')
↓
['filter',
['property',
['ident', 'filter']],
['propertyDelim'],
['filterv',
['progid',
['raw', 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src='a.png',sizingMethod='scale')']]]]
Function.
Consists of:
- ident (function name), and
- functionBody (function body).
color: rgb(255,0,0)
↓
['declaration',
['property',
['ident', 'color']],
['propertyDelim'],
['value',
['s', ' '],
['function',
['ident', 'rgb'],
['functionBody',
['number', '255'],
['operator', ','],
['number', '0'],
['operator', ','],
['number', '0']]]]]
Node to store expression
.
left:expression(document.body.offsetWidth+1)
↓
['declaration',
['property',
['ident', 'left']],
['propertyDelim'],
['value',
['functionExpression', 'document.body.offsetWidth+1']]]
Identifiers or names.
In atkeyword:
@import ..;
↓
['atkeyword',
['ident', 'import']]
In class:
.abc
↓
['class',
['ident', 'abc']]
In dimension:
10px
↓
['dimension',
['number', '10'],
['ident', 'px']]
!important
keyword.
a: b !important
↓
['declaration',
['property',
['ident', 'a']],
['propertyDelim'],
['value',
['s', ' '],
['ident', 'b'],
['s', ' '],
['important']]]
Included mixin.
For scss and sass:
@include nani
↓
['include',
['atkeyword',
['ident', 'include']],
['s', ' '],
['simpleselector',
['ident', 'nani']]]
For less:
.nani(2px)
↓
['include',
['class',
['ident', 'nani']],
['arguments',
['dimension',
['number', '2'],
['ident', 'px']]]]
Interpolated variable.
For scss and sass:
#{$nani}
↓
['interpolatedVariable',
['ident', 'nani']]
For less:
@{nani}
↓
['interpolatedVariable',
['ident', 'nani']]
Valid only for scss and sass.
@while 1 > 2 {a{p:v}}
↓
['loop',
['atkeyword',
['ident', 'while']],
['s', ' '],
['number', '1'],
['s', ' '],
['operator', '>'],
['s', ' '],
['number', '2'],
['s', ' '],
['block',
['ruleset',
['selector',
['simpleselector',
['ident', 'a']]],
['block',
['declaration',
['property',
['ident', 'p']],
['propertyDelim'],
['value',
['ident', 'v']]]]]]]
For scss and sass:
@mixin nani {color:tomato}
↓
['mixin',
['atkeyword',
['ident', 'mixin']],
['s', ' '],
['ident', 'nani'],
['s', ' '],
['block',
['declaration',
['property',
['ident', 'color']],
['propertyDelim'],
['value',
['ident', 'tomato']]]]]
For less:
.nani (@color) {color:@color}
↓
['mixin',
['class',
['ident', 'nani']],
['s', ' '],
['arguments',
['variable',
['ident', 'color']]],
['s', ' '],
['block',
['declaration',
['property',
['ident', 'color']],
['propertyDelim'],
['value',
['variable',
['ident', 'color']]]]]]
Namespace sign in simpleselector.
*|E { .. }
↓
['simpleselector',
['ident', '*'],
['namespace'],
['ident', 'E']]
Numbers and identifiers in nthselector.
:nth-child(2n+1)
↓
['nthselector',
['ident', 'nth-child'],
['nth', '2n'],
['unary', '+'],
['nth', '1']]
:nth-
pseudo-classes.
It consists of a pseudo-class ident and content.
:nth-last-child(+3n-2)
↓
['nthselector',
['ident', 'nth-last-child'],
['unary', '+'],
['nth', '3n'],
['unary', '-'],
['nth', '2']]
Number.
10
12.34
↓
['number', '10']
['number', '12.34']
Operator: /
, ,
, :
, =
.
test(x,y)
↓
['function',
['ident', 'test'],
['functionBody',
['ident', 'x'],
['operator', ','],
['ident', 'y']]]
Valid only for less, scss and sass.
&.nani
↓
['parentselector'],
['class',
['ident', 'nani']]
Number with percent sign.
10%
↓
['percentage',
['number', '10']]
Placeholder.
Valid only for scss and sass.
%button
↓
['placeholder',
['ident', 'button']]
CSS property.
top:0
$color: tomato
↓
['declaration',
['property',
['ident', 'top']],
['propertyDelim'],
['value',
['number', '0']]]
['declaration',
['property',
['variable', 'color']],
['propertyDelim'],
['value',
['ident', 'tomato']]]
Delimiter :
between property and value.
color: tomato
↓
['declaration',
['property',
['ident', 'color']],
['propertyDelim'],
['value',
['s', ' '],
['ident', 'tomato']]]
Sass allows you to put :
before property:
:color tomato
↓
['declaration',
['propertyDelim'],
['property',
['ident', 'color'],
['s', ' ']],
['value',
['ident', 'tomato']]]
Pseudo-class.
test:visited
↓
['simpleselector',
['ident', 'test'],
['pseudoc',
['ident', 'visited']]]
Pseudo-element.
p::first-line
↓
['simpleselector',
['ident', 'p'],
['pseudoe',
['ident', 'first-line']]]
Unparsed parts of the style. Refers to a specific browser specific extensions,
usually IE filter
.
progid:DXImageTransform.Microsoft.AlphaImageLoader(src='a.png',sizingMethod='scale')
↓
['progid',
['raw', 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src='a.png',sizingMethod='scale')']]]]
A set of rules with selectors.
Consists of:
- selector (selector), and
- block (a set of rules).
x, y {p:v}
↓
['ruleset',
['selector',
['simpleselector',
['ident', 'x']],
['delim'],
['simpleselector',
['s', ' '],
['ident', 'y'],
['s', ' ']]],
['block',
['declaration',
['property',
['ident', 'p']],
['propertyDelim'],
['value',
['ident', 'v']]]]]
Whitespace: space, \t
, \n
, \r
.
/*a*/ /*b*/
↓
['commentML', 'a'],
['s', ' '],
['commentML', 'b']
Node to store simpleselector groups.
x, y, [a=b] { .. }
↓
['selector',
['simpleselector',
['ident', 'x']],
['delim'],
['simpleselector',
['s', ' '],
['ident', 'y']],
['delim'],
['simpleselector',
['s', ' '],
['attrib',
['ident', 'a'],
['attrselector', '='],
['ident', 'b']],
['s', ' ']]]
Hexadecimal number in simpleselector.
.. #FFF .. { .. }
↓
['shash', 'FFF']
Sets of selectors between a commas.
x, y+z { .. }
↓
['selector',
['simpleselector',
['ident', 'x']],
['delim'],
['simpleselector',
['s', ' '],
['ident', 'y'],
['combinator', '+'],
['ident', 'z'],
['s', ' ']]]
String wraped with single or double quotes.
'test'
"test"
↓
['string', ''test'']
['string', '"test"']
Style. The root node of AST.
Can consist of:
- rulesets (sets of rules with selectors),
- @-rules,
- whitespaces,
- single-line comments,
- multi-line comments.
@import "x.png"; /*sample*/ x{p:v}
↓
['stylesheet',
['atrules',
['atkeyword',
['ident', 'import']],
['s', ' '],
['string', '"x.png"']],
['s', ' '],
['commentML', 'sample'],
['s', ' '],
['ruleset',
['selector',
['simpleselector',
['ident', 'x']]],
['block',
['declaration',
['property',
['ident', 'p']],
['propertyDelim'],
['value',
['ident', 'v']]]]]]
Unary (or arithmetical) sign: +
, -
.
nth-last-child(3n+0)
↓
['nthselector',
['ident', 'nth-last-child'],
['nth', '3n'],
['unary', '+'],
['nth', '0']]
Node to store invalid (or unknown) parts of the style, that parser can extract and continue on.
// invalid
↓
['stylesheet',
['unknown', '// invalid']]
URI.
@import url('/css/styles.css')
↓
['atrules',
['atkeyword',
['ident', 'import']],
['s', ' '],
['uri',
['string', ''/css/styles.css'']]]
Value of a property.
color: tomato
↓
['declaration',
['property',
['ident', 'color']],
['propertyDelim'],
['value',
['s', ' '],
['ident', 'tomato']]]
Valid for less, scss and sass.
Sass:
$color
↓
['variable',
['ident', 'color']]
LESS:
@color
@@foo
↓
['variable',
['ident', 'color']]
['variable',
['variable',
['ident', 'foo']]]
Valid for less, scss and sass.
Sass:
$arguments...
↓
['variableslist',
['variable',
['ident', 'arguments']]]
LESS:
@rest...
↓
['variableslist',
['variable',
['ident', 'rest']]]
Hexadecimal number in value.
.. { ..: #FFF }
↓
['vhash', 'FFF']