stylus-source 0.15.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/README.md +3 -0
- data/lib/.DS_Store +0 -0
- data/lib/node_modules/cssom/.idea/CSSOM.iml +9 -0
- data/lib/node_modules/cssom/.idea/dictionaries/nv.xml +3 -0
- data/lib/node_modules/cssom/.idea/encodings.xml +5 -0
- data/lib/node_modules/cssom/.idea/misc.xml +17 -0
- data/lib/node_modules/cssom/.idea/modules.xml +9 -0
- data/lib/node_modules/cssom/.idea/projectCodeStyle.xml +82 -0
- data/lib/node_modules/cssom/.idea/vcs.xml +8 -0
- data/lib/node_modules/cssom/.idea/workspace.xml +467 -0
- data/lib/node_modules/cssom/.livereload +19 -0
- data/lib/node_modules/cssom/Jakefile +37 -0
- data/lib/node_modules/cssom/README.mdown +33 -0
- data/lib/node_modules/cssom/Rakefile +23 -0
- data/lib/node_modules/cssom/docs/.livereload +19 -0
- data/lib/node_modules/cssom/docs/bar.css +3 -0
- data/lib/node_modules/cssom/docs/demo.css +0 -0
- data/lib/node_modules/cssom/docs/foo.css +4 -0
- data/lib/node_modules/cssom/docs/parse.html +170 -0
- data/lib/node_modules/cssom/docs/parse2.html +431 -0
- data/lib/node_modules/cssom/index.html +100 -0
- data/lib/node_modules/cssom/lib/CSSImportRule.js +34 -0
- data/lib/node_modules/cssom/lib/CSSMediaRule.js +38 -0
- data/lib/node_modules/cssom/lib/CSSOM.js +3 -0
- data/lib/node_modules/cssom/lib/CSSRule.js +38 -0
- data/lib/node_modules/cssom/lib/CSSStyleDeclaration.js +130 -0
- data/lib/node_modules/cssom/lib/CSSStyleRule.js +187 -0
- data/lib/node_modules/cssom/lib/CSSStyleSheet.js +85 -0
- data/lib/node_modules/cssom/lib/MediaList.js +61 -0
- data/lib/node_modules/cssom/lib/StyleSheet.js +15 -0
- data/lib/node_modules/cssom/lib/clone.js +69 -0
- data/lib/node_modules/cssom/lib/index.js +10 -0
- data/lib/node_modules/cssom/lib/parse.js +195 -0
- data/lib/node_modules/cssom/media.html +17 -0
- data/lib/node_modules/cssom/package.json +30 -0
- data/lib/node_modules/cssom/plugins/toHTML.js +32 -0
- data/lib/node_modules/cssom/server/index.html +22 -0
- data/lib/node_modules/cssom/server/index.js +21 -0
- data/lib/node_modules/cssom/shorthands.html +21 -0
- data/lib/node_modules/cssom/test/CSSStyleDeclaration.test.js +35 -0
- data/lib/node_modules/cssom/test/CSSStyleRule.test.js +12 -0
- data/lib/node_modules/cssom/test/CSSStyleSheet.test.js +16 -0
- data/lib/node_modules/cssom/test/MediaList.test.js +21 -0
- data/lib/node_modules/cssom/test/clone.test.js +38 -0
- data/lib/node_modules/cssom/test/fixtures/dummy.css +3 -0
- data/lib/node_modules/cssom/test/helper.js +97 -0
- data/lib/node_modules/cssom/test/index.html +42 -0
- data/lib/node_modules/cssom/test/parse.test.js +346 -0
- data/lib/node_modules/cssom/test/vendor/qunit.css +189 -0
- data/lib/node_modules/cssom/test/vendor/qunit.js +1341 -0
- data/lib/node_modules/growl/History.md +16 -0
- data/lib/node_modules/growl/Readme.md +74 -0
- data/lib/node_modules/growl/lib/growl.js +82 -0
- data/lib/node_modules/growl/package.json +6 -0
- data/lib/node_modules/growl/test.js +17 -0
- data/lib/stylus/colors.js +156 -0
- data/lib/stylus/convert/css.js +130 -0
- data/lib/stylus/errors.js +58 -0
- data/lib/stylus/functions/image.js +120 -0
- data/lib/stylus/functions/index.js +722 -0
- data/lib/stylus/functions/index.styl +123 -0
- data/lib/stylus/functions/url.js +98 -0
- data/lib/stylus/lexer.js +728 -0
- data/lib/stylus/middleware.js +223 -0
- data/lib/stylus/nodes/arguments.js +65 -0
- data/lib/stylus/nodes/binop.js +54 -0
- data/lib/stylus/nodes/block.js +99 -0
- data/lib/stylus/nodes/boolean.js +103 -0
- data/lib/stylus/nodes/call.js +57 -0
- data/lib/stylus/nodes/charset.js +42 -0
- data/lib/stylus/nodes/comment.js +32 -0
- data/lib/stylus/nodes/each.js +56 -0
- data/lib/stylus/nodes/expression.js +168 -0
- data/lib/stylus/nodes/fontface.js +55 -0
- data/lib/stylus/nodes/function.js +104 -0
- data/lib/stylus/nodes/group.js +79 -0
- data/lib/stylus/nodes/hsla.js +256 -0
- data/lib/stylus/nodes/ident.js +127 -0
- data/lib/stylus/nodes/if.js +55 -0
- data/lib/stylus/nodes/import.js +30 -0
- data/lib/stylus/nodes/index.js +52 -0
- data/lib/stylus/nodes/jsliteral.js +32 -0
- data/lib/stylus/nodes/keyframes.js +78 -0
- data/lib/stylus/nodes/literal.js +92 -0
- data/lib/stylus/nodes/media.js +42 -0
- data/lib/stylus/nodes/node.js +209 -0
- data/lib/stylus/nodes/null.js +72 -0
- data/lib/stylus/nodes/page.js +43 -0
- data/lib/stylus/nodes/params.js +72 -0
- data/lib/stylus/nodes/property.js +72 -0
- data/lib/stylus/nodes/return.js +44 -0
- data/lib/stylus/nodes/rgba.js +335 -0
- data/lib/stylus/nodes/root.js +50 -0
- data/lib/stylus/nodes/selector.js +57 -0
- data/lib/stylus/nodes/string.js +120 -0
- data/lib/stylus/nodes/ternary.js +51 -0
- data/lib/stylus/nodes/unaryop.js +46 -0
- data/lib/stylus/nodes/unit.js +207 -0
- data/lib/stylus/parser.js +1514 -0
- data/lib/stylus/renderer.js +157 -0
- data/lib/stylus/source.rb +7 -0
- data/lib/stylus/stack/frame.js +66 -0
- data/lib/stylus/stack/index.js +146 -0
- data/lib/stylus/stack/scope.js +53 -0
- data/lib/stylus/stylus.js +102 -0
- data/lib/stylus/token.js +53 -0
- data/lib/stylus/utils.js +237 -0
- data/lib/stylus/visitor/compiler.js +472 -0
- data/lib/stylus/visitor/evaluator.js +1070 -0
- data/lib/stylus/visitor/index.js +31 -0
- data/stylus-source.gemspec +15 -0
- metadata +158 -0
@@ -0,0 +1,123 @@
|
|
1
|
+
|
2
|
+
vendors = moz webkit official
|
3
|
+
|
4
|
+
// stringify the given arg
|
5
|
+
|
6
|
+
-string(arg)
|
7
|
+
type(arg) + ' ' + arg
|
8
|
+
|
9
|
+
// require a color
|
10
|
+
|
11
|
+
require-color(color)
|
12
|
+
unless color is a 'color'
|
13
|
+
error('RGB or HSL value expected, got a ' + -string(color))
|
14
|
+
|
15
|
+
// require a unit
|
16
|
+
|
17
|
+
require-unit(n)
|
18
|
+
unless n is a 'unit'
|
19
|
+
error('unit expected, got a ' + -string(n))
|
20
|
+
|
21
|
+
// require a string
|
22
|
+
|
23
|
+
require-string(str)
|
24
|
+
unless str is a 'string' or str is a 'ident'
|
25
|
+
error('string expected, got a ' + -string(str))
|
26
|
+
|
27
|
+
// apply js Math function
|
28
|
+
|
29
|
+
math(n, fn)
|
30
|
+
require-unit(n)
|
31
|
+
require-string(fn)
|
32
|
+
-math(n, fn)
|
33
|
+
|
34
|
+
// adjust the given color's property by amount
|
35
|
+
|
36
|
+
adjust(color, prop, amount)
|
37
|
+
require-color(color)
|
38
|
+
require-string(prop)
|
39
|
+
require-unit(amount)
|
40
|
+
-adjust(color, prop, amount)
|
41
|
+
|
42
|
+
// Math functions
|
43
|
+
|
44
|
+
abs(n) { math(n, 'abs') }
|
45
|
+
ceil(n) { math(n, 'ceil') }
|
46
|
+
floor(n) { math(n, 'floor') }
|
47
|
+
round(n) { math(n, 'round') }
|
48
|
+
sin(n) { math(n, 'sin') }
|
49
|
+
cos(n) { math(n, 'cos') }
|
50
|
+
min(a, b) { a < b ? a : b }
|
51
|
+
max(a, b) { a > b ? a : b }
|
52
|
+
PI = -math-prop('PI')
|
53
|
+
|
54
|
+
// return the sum of the given numbers
|
55
|
+
|
56
|
+
sum(nums)
|
57
|
+
sum = 0
|
58
|
+
sum += n for n in nums
|
59
|
+
|
60
|
+
// return the average of the given numbers
|
61
|
+
|
62
|
+
avg(nums)
|
63
|
+
sum(nums) / length(nums)
|
64
|
+
|
65
|
+
// color components
|
66
|
+
|
67
|
+
alpha(color) { component(hsl(color), 'alpha') }
|
68
|
+
hue(color) { component(hsl(color), 'hue') }
|
69
|
+
saturation(color) { component(hsl(color), 'saturation') }
|
70
|
+
lightness(color) { component(hsl(color), 'lightness') }
|
71
|
+
|
72
|
+
// check if n is an odd number
|
73
|
+
|
74
|
+
odd(n)
|
75
|
+
1 == n % 2
|
76
|
+
|
77
|
+
// check if n is an even number
|
78
|
+
|
79
|
+
even(n)
|
80
|
+
0 == n % 2
|
81
|
+
|
82
|
+
// check if color is light
|
83
|
+
|
84
|
+
light(color)
|
85
|
+
lightness(color) >= 50%
|
86
|
+
|
87
|
+
// check if color is dark
|
88
|
+
|
89
|
+
dark(color)
|
90
|
+
lightness(color) < 50%
|
91
|
+
|
92
|
+
// desaturate color by amount
|
93
|
+
|
94
|
+
desaturate(color, amount)
|
95
|
+
adjust(color, 'saturation', - amount)
|
96
|
+
|
97
|
+
// saturate color by amount
|
98
|
+
|
99
|
+
saturate(color, amount)
|
100
|
+
adjust(color, 'saturation', amount)
|
101
|
+
|
102
|
+
// darken by the given amount
|
103
|
+
|
104
|
+
darken(color, amount)
|
105
|
+
adjust(color, 'lightness', - amount)
|
106
|
+
|
107
|
+
// lighten by the given amount
|
108
|
+
|
109
|
+
lighten(color, amount)
|
110
|
+
adjust(color, 'lightness', amount)
|
111
|
+
|
112
|
+
// return the last value in the given expr
|
113
|
+
|
114
|
+
last(expr)
|
115
|
+
expr[length(expr) - 1]
|
116
|
+
|
117
|
+
// join values with the given delimiter
|
118
|
+
|
119
|
+
join(delim, vals...)
|
120
|
+
buf = ''
|
121
|
+
vals = vals[0] if length(vals) == 1
|
122
|
+
for val, i in vals
|
123
|
+
buf += i ? delim + val : val
|
@@ -0,0 +1,98 @@
|
|
1
|
+
|
2
|
+
/*!
|
3
|
+
* Stylus - plugin - url
|
4
|
+
* Copyright(c) 2010 LearnBoost <dev@learnboost.com>
|
5
|
+
* MIT Licensed
|
6
|
+
*/
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Module dependencies.
|
10
|
+
*/
|
11
|
+
|
12
|
+
var Compiler = require('../visitor/compiler')
|
13
|
+
, nodes = require('../nodes')
|
14
|
+
, parse = require('url').parse
|
15
|
+
, extname = require('path').extname
|
16
|
+
, utils = require('../utils')
|
17
|
+
, fs = require('fs');
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Mime table.
|
21
|
+
*/
|
22
|
+
|
23
|
+
var mimes = {
|
24
|
+
'.gif': 'image/gif'
|
25
|
+
, '.png': 'image/png'
|
26
|
+
, '.jpg': 'image/jpeg'
|
27
|
+
, '.jpeg': 'image/jpeg'
|
28
|
+
, '.svg': 'image/svg+xml'
|
29
|
+
};
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Return a url() function with the given `options`.
|
33
|
+
*
|
34
|
+
* Options:
|
35
|
+
*
|
36
|
+
* - `limit` bytesize limit defaulting to 30Kb
|
37
|
+
* - `paths` image resolution path(s), merged with general lookup paths
|
38
|
+
*
|
39
|
+
* Examples:
|
40
|
+
*
|
41
|
+
* stylus(str)
|
42
|
+
* .set('filename', __dirname + '/css/test.styl')
|
43
|
+
* .define('url', stylus.url({ paths: [__dirname + '/public'] }))
|
44
|
+
* .render(function(err, css){ ... })
|
45
|
+
*
|
46
|
+
* @param {Object} options
|
47
|
+
* @return {Function}
|
48
|
+
* @api public
|
49
|
+
*/
|
50
|
+
|
51
|
+
module.exports = function(options) {
|
52
|
+
options = options || {};
|
53
|
+
|
54
|
+
var sizeLimit = options.limit || 30000
|
55
|
+
, _paths = options.paths || [];
|
56
|
+
|
57
|
+
function url(url){
|
58
|
+
// Compile the url
|
59
|
+
var compiler = new Compiler(url);
|
60
|
+
compiler.isURL = true;
|
61
|
+
var url = url.nodes.map(function(node){
|
62
|
+
return compiler.visit(node);
|
63
|
+
}).join('');
|
64
|
+
|
65
|
+
// Parse literal
|
66
|
+
var url = parse(url)
|
67
|
+
, ext = extname(url.pathname)
|
68
|
+
, mime = mimes[ext]
|
69
|
+
, literal = new nodes.Literal('url("' + url.href + '")')
|
70
|
+
, paths = _paths.concat(this.paths)
|
71
|
+
, founds
|
72
|
+
, buf;
|
73
|
+
|
74
|
+
// Not supported
|
75
|
+
if (!mime) return literal;
|
76
|
+
|
77
|
+
// Absolute
|
78
|
+
if (url.protocol) return literal;
|
79
|
+
|
80
|
+
// Lookup
|
81
|
+
found = utils.lookup(url.pathname, paths);
|
82
|
+
|
83
|
+
// Failed to lookup
|
84
|
+
if (!found) return literal;
|
85
|
+
|
86
|
+
// Read data
|
87
|
+
buf = fs.readFileSync(found);
|
88
|
+
|
89
|
+
// To large
|
90
|
+
if (buf.length > sizeLimit) return literal;
|
91
|
+
|
92
|
+
// Encode
|
93
|
+
return new nodes.Literal('url("data:' + mime + ';base64,' + buf.toString('base64') + '")');
|
94
|
+
};
|
95
|
+
|
96
|
+
url.raw = true;
|
97
|
+
return url;
|
98
|
+
};
|
data/lib/stylus/lexer.js
ADDED
@@ -0,0 +1,728 @@
|
|
1
|
+
|
2
|
+
/*!
|
3
|
+
* Stylus - Lexer
|
4
|
+
* Copyright(c) 2010 LearnBoost <dev@learnboost.com>
|
5
|
+
* MIT Licensed
|
6
|
+
*/
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Module dependencies.
|
10
|
+
*/
|
11
|
+
|
12
|
+
var Token = require('./token')
|
13
|
+
, nodes = require('./nodes')
|
14
|
+
, errors = require('./errors');
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Operator aliases.
|
18
|
+
*/
|
19
|
+
|
20
|
+
var alias = {
|
21
|
+
'and': '&&'
|
22
|
+
, 'or': '||'
|
23
|
+
, 'is': '=='
|
24
|
+
, 'isnt': '!='
|
25
|
+
, 'is not': '!='
|
26
|
+
, ':=': '?='
|
27
|
+
};
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Units.
|
31
|
+
*/
|
32
|
+
|
33
|
+
var units = [
|
34
|
+
'em'
|
35
|
+
, 'ex'
|
36
|
+
, 'px'
|
37
|
+
, 'mm'
|
38
|
+
, 'cm'
|
39
|
+
, 'in'
|
40
|
+
, 'pt'
|
41
|
+
, 'pc'
|
42
|
+
, 'deg'
|
43
|
+
, 'rad'
|
44
|
+
, 'grad'
|
45
|
+
, 'ms'
|
46
|
+
, 's'
|
47
|
+
, 'Hz'
|
48
|
+
, 'kHz'
|
49
|
+
, 'rem'
|
50
|
+
, '%'].join('|');
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Unit RegExp.
|
54
|
+
*/
|
55
|
+
|
56
|
+
var unit = new RegExp('^(-)?(\\d+\\.\\d+|\\d+|\\.\\d+)(' + units + ')? *');
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Initialize a new `Lexer` with the given `str` and `options`.
|
60
|
+
*
|
61
|
+
* @param {String} str
|
62
|
+
* @param {Object} options
|
63
|
+
* @api private
|
64
|
+
*/
|
65
|
+
|
66
|
+
var Lexer = module.exports = function Lexer(str, options) {
|
67
|
+
options = options || {};
|
68
|
+
this.str = str.replace(/\r\n?/g, '\n');
|
69
|
+
this.stash = [];
|
70
|
+
this.indentStack = [];
|
71
|
+
this.indentRe = null;
|
72
|
+
this.lineno = 1;
|
73
|
+
};
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Lexer prototype.
|
77
|
+
*/
|
78
|
+
|
79
|
+
Lexer.prototype = {
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Custom inspect.
|
83
|
+
*/
|
84
|
+
|
85
|
+
inspect: function(){
|
86
|
+
var tok
|
87
|
+
, tmp = this.str
|
88
|
+
, buf = [];
|
89
|
+
while ('eos' != (tok = this.next()).type) {
|
90
|
+
buf.push(tok.inspect());
|
91
|
+
}
|
92
|
+
this.str = tmp;
|
93
|
+
this.prevIndents = 0;
|
94
|
+
return buf.concat(tok.inspect()).join('\n');
|
95
|
+
},
|
96
|
+
|
97
|
+
/**
|
98
|
+
* Lookahead `n` tokens.
|
99
|
+
*
|
100
|
+
* @param {Number} n
|
101
|
+
* @return {Object}
|
102
|
+
* @api private
|
103
|
+
*/
|
104
|
+
|
105
|
+
lookahead: function(n){
|
106
|
+
var fetch = n - this.stash.length;
|
107
|
+
while (fetch-- > 0) this.stash.push(this.advance());
|
108
|
+
return this.stash[--n];
|
109
|
+
},
|
110
|
+
|
111
|
+
/**
|
112
|
+
* Consume the given `len`.
|
113
|
+
*
|
114
|
+
* @param {Number|Array} len
|
115
|
+
* @api private
|
116
|
+
*/
|
117
|
+
|
118
|
+
skip: function(len){
|
119
|
+
this.str = this.str.substr(Array.isArray(len)
|
120
|
+
? len[0].length
|
121
|
+
: len);
|
122
|
+
},
|
123
|
+
|
124
|
+
/**
|
125
|
+
* Fetch next token including those stashed by peek.
|
126
|
+
*
|
127
|
+
* @return {Token}
|
128
|
+
* @api private
|
129
|
+
*/
|
130
|
+
|
131
|
+
next: function() {
|
132
|
+
var tok = this.stashed() || this.advance();
|
133
|
+
switch (tok.type) {
|
134
|
+
case 'newline':
|
135
|
+
case 'indent':
|
136
|
+
++this.lineno;
|
137
|
+
break;
|
138
|
+
case 'outdent':
|
139
|
+
if ('outdent' != this.prev.type) ++this.lineno;
|
140
|
+
}
|
141
|
+
this.prev = tok;
|
142
|
+
tok.lineno = this.lineno;
|
143
|
+
return tok;
|
144
|
+
},
|
145
|
+
|
146
|
+
/**
|
147
|
+
* Fetch next token.
|
148
|
+
*
|
149
|
+
* @return {Token}
|
150
|
+
* @api private
|
151
|
+
*/
|
152
|
+
|
153
|
+
advance: function() {
|
154
|
+
return this.eos()
|
155
|
+
|| this.null()
|
156
|
+
|| this.sep()
|
157
|
+
|| this.keyword()
|
158
|
+
|| this.urlchars()
|
159
|
+
|| this.atrule()
|
160
|
+
|| this.media()
|
161
|
+
|| this.comment()
|
162
|
+
|| this.newline()
|
163
|
+
|| this.escaped()
|
164
|
+
|| this.important()
|
165
|
+
|| this.literal()
|
166
|
+
|| this.function()
|
167
|
+
|| this.brace()
|
168
|
+
|| this.paren()
|
169
|
+
|| this.color()
|
170
|
+
|| this.string()
|
171
|
+
|| this.unit()
|
172
|
+
|| this.namedop()
|
173
|
+
|| this.boolean()
|
174
|
+
|| this.ident()
|
175
|
+
|| this.op()
|
176
|
+
|| this.space()
|
177
|
+
|| this.selector();
|
178
|
+
},
|
179
|
+
|
180
|
+
/**
|
181
|
+
* Lookahead a single token.
|
182
|
+
*
|
183
|
+
* @return {Token}
|
184
|
+
* @api private
|
185
|
+
*/
|
186
|
+
|
187
|
+
peek: function() {
|
188
|
+
return this.lookahead(1);
|
189
|
+
},
|
190
|
+
|
191
|
+
/**
|
192
|
+
* Return the next possibly stashed token.
|
193
|
+
*
|
194
|
+
* @return {Token}
|
195
|
+
* @api private
|
196
|
+
*/
|
197
|
+
|
198
|
+
stashed: function() {
|
199
|
+
return this.stash.shift();
|
200
|
+
},
|
201
|
+
|
202
|
+
/**
|
203
|
+
* EOS | trailing outdents.
|
204
|
+
*/
|
205
|
+
|
206
|
+
eos: function() {
|
207
|
+
if (this.str.length) return;
|
208
|
+
if (this.indentStack.length) {
|
209
|
+
this.indentStack.shift();
|
210
|
+
return new Token('outdent');
|
211
|
+
} else {
|
212
|
+
return new Token('eos');
|
213
|
+
}
|
214
|
+
},
|
215
|
+
|
216
|
+
/**
|
217
|
+
* url char
|
218
|
+
*/
|
219
|
+
|
220
|
+
urlchars: function() {
|
221
|
+
var captures;
|
222
|
+
if (!this.isURL) return;
|
223
|
+
if (captures = /^[\/:@.;?&=*!,<>#%0-9]+/.exec(this.str)) {
|
224
|
+
this.skip(captures);
|
225
|
+
return new Token('literal', new nodes.Literal(captures[0]));
|
226
|
+
}
|
227
|
+
},
|
228
|
+
|
229
|
+
/**
|
230
|
+
* ';' ' '*
|
231
|
+
*/
|
232
|
+
|
233
|
+
sep: function() {
|
234
|
+
var captures;
|
235
|
+
if (captures = /^; */.exec(this.str)) {
|
236
|
+
this.skip(captures);
|
237
|
+
return new Token(';');
|
238
|
+
}
|
239
|
+
},
|
240
|
+
|
241
|
+
/**
|
242
|
+
* ' '+
|
243
|
+
*/
|
244
|
+
|
245
|
+
space: function() {
|
246
|
+
var captures;
|
247
|
+
if (captures = /^( +)/.exec(this.str)) {
|
248
|
+
this.skip(captures);
|
249
|
+
return new Token('space');
|
250
|
+
}
|
251
|
+
},
|
252
|
+
|
253
|
+
/**
|
254
|
+
* '\\' . ' '*
|
255
|
+
*/
|
256
|
+
|
257
|
+
escaped: function() {
|
258
|
+
var captures;
|
259
|
+
if (captures = /^\\(.) */.exec(this.str)) {
|
260
|
+
var c = captures[1];
|
261
|
+
this.skip(captures);
|
262
|
+
return new Token('ident', new nodes.Literal(c));
|
263
|
+
}
|
264
|
+
},
|
265
|
+
|
266
|
+
/**
|
267
|
+
* '@css' ' '* '{' .* '}' ' '*
|
268
|
+
*/
|
269
|
+
|
270
|
+
literal: function() {
|
271
|
+
// HACK attack !!!
|
272
|
+
var captures;
|
273
|
+
if (captures = /^@css *\{/.exec(this.str)) {
|
274
|
+
this.skip(captures);
|
275
|
+
var c
|
276
|
+
, braces = 1
|
277
|
+
, css = '';
|
278
|
+
while (c = this.str[0]) {
|
279
|
+
this.str = this.str.substr(1);
|
280
|
+
switch (c) {
|
281
|
+
case '{': ++braces; break;
|
282
|
+
case '}': --braces; break;
|
283
|
+
}
|
284
|
+
css += c;
|
285
|
+
if (!braces) break;
|
286
|
+
}
|
287
|
+
css = css.replace(/\s*}$/, '');
|
288
|
+
return new Token('literal', new nodes.Literal(css));
|
289
|
+
}
|
290
|
+
},
|
291
|
+
|
292
|
+
/**
|
293
|
+
* '!important' ' '*
|
294
|
+
*/
|
295
|
+
|
296
|
+
important: function() {
|
297
|
+
var captures;
|
298
|
+
if (captures = /^!important */.exec(this.str)) {
|
299
|
+
this.skip(captures);
|
300
|
+
return new Token('ident', new nodes.Literal('!important'));
|
301
|
+
}
|
302
|
+
},
|
303
|
+
|
304
|
+
/**
|
305
|
+
* '{' | '}'
|
306
|
+
*/
|
307
|
+
|
308
|
+
brace: function() {
|
309
|
+
var captures;
|
310
|
+
if (captures = /^([{}])/.exec(this.str)) {
|
311
|
+
this.skip(1);
|
312
|
+
var brace = captures[1];
|
313
|
+
return new Token(brace, brace);
|
314
|
+
}
|
315
|
+
},
|
316
|
+
|
317
|
+
/**
|
318
|
+
* '(' | ')' ' '*
|
319
|
+
*/
|
320
|
+
|
321
|
+
paren: function() {
|
322
|
+
var captures;
|
323
|
+
if (captures = /^([()]) */.exec(this.str)) {
|
324
|
+
var paren = captures[1];
|
325
|
+
this.skip(captures);
|
326
|
+
if (')' == paren) this.isURL = false;
|
327
|
+
return new Token(paren, paren);
|
328
|
+
}
|
329
|
+
},
|
330
|
+
|
331
|
+
/**
|
332
|
+
* 'null'
|
333
|
+
*/
|
334
|
+
|
335
|
+
null: function() {
|
336
|
+
var captures;
|
337
|
+
if (captures = /^(null)\b */.exec(this.str)) {
|
338
|
+
this.skip(captures);
|
339
|
+
return new Token('null', nodes.null);
|
340
|
+
}
|
341
|
+
},
|
342
|
+
|
343
|
+
/**
|
344
|
+
* 'if'
|
345
|
+
* | 'else'
|
346
|
+
* | 'unless'
|
347
|
+
* | 'return'
|
348
|
+
* | 'for'
|
349
|
+
* | 'in'
|
350
|
+
*/
|
351
|
+
|
352
|
+
keyword: function() {
|
353
|
+
var captures;
|
354
|
+
if (captures = /^(return|if|else|unless|for|in)\b */.exec(this.str)) {
|
355
|
+
var keyword = captures[1];
|
356
|
+
this.skip(captures);
|
357
|
+
return new Token(keyword, keyword);
|
358
|
+
}
|
359
|
+
},
|
360
|
+
|
361
|
+
/**
|
362
|
+
* 'not'
|
363
|
+
* | 'and'
|
364
|
+
* | 'or'
|
365
|
+
* | 'is'
|
366
|
+
* | 'is not'
|
367
|
+
* | 'isnt'
|
368
|
+
* | 'is a'
|
369
|
+
* | 'is defined'
|
370
|
+
*/
|
371
|
+
|
372
|
+
namedop: function() {
|
373
|
+
var captures;
|
374
|
+
if (captures = /^(not|and|or|is a|is defined|isnt|is not|is)\b( *)/.exec(this.str)) {
|
375
|
+
var op = captures[1];
|
376
|
+
this.skip(captures);
|
377
|
+
op = alias[op] || op;
|
378
|
+
var tok = new Token(op, op);
|
379
|
+
tok.space = captures[2];
|
380
|
+
return tok;
|
381
|
+
}
|
382
|
+
},
|
383
|
+
|
384
|
+
/**
|
385
|
+
* ','
|
386
|
+
* | '+'
|
387
|
+
* | '+='
|
388
|
+
* | '-'
|
389
|
+
* | '-='
|
390
|
+
* | '*'
|
391
|
+
* | '*='
|
392
|
+
* | '/'
|
393
|
+
* | '/='
|
394
|
+
* | '%'
|
395
|
+
* | '%='
|
396
|
+
* | '**'
|
397
|
+
* | '!'
|
398
|
+
* | '&'
|
399
|
+
* | '&&'
|
400
|
+
* | '||'
|
401
|
+
* | '>'
|
402
|
+
* | '>='
|
403
|
+
* | '<'
|
404
|
+
* | '<='
|
405
|
+
* | '='
|
406
|
+
* | '=='
|
407
|
+
* | '!='
|
408
|
+
* | '!'
|
409
|
+
* | '~'
|
410
|
+
* | '?='
|
411
|
+
* | ':='
|
412
|
+
* | '?'
|
413
|
+
* | ':'
|
414
|
+
* | '['
|
415
|
+
* | ']'
|
416
|
+
* | '..'
|
417
|
+
* | '...'
|
418
|
+
*/
|
419
|
+
|
420
|
+
op: function() {
|
421
|
+
var captures;
|
422
|
+
if (captures = /^([.]{2,3}|&&|\|\||[!<>=?:]=|\*\*|[-+*\/%]=?|[,=?:!~<>&\[\]])( *)/.exec(this.str)) {
|
423
|
+
var op = captures[1];
|
424
|
+
this.skip(captures);
|
425
|
+
op = alias[op] || op;
|
426
|
+
var tok = new Token(op, op);
|
427
|
+
tok.space = captures[2];
|
428
|
+
return tok;
|
429
|
+
}
|
430
|
+
},
|
431
|
+
|
432
|
+
/**
|
433
|
+
* '@media' ([^{\n]+)
|
434
|
+
*/
|
435
|
+
|
436
|
+
media: function() {
|
437
|
+
var captures;
|
438
|
+
if (captures = /^@media *([^{\n]+)/.exec(this.str)) {
|
439
|
+
this.skip(captures);
|
440
|
+
return new Token('media', captures[1].trim());
|
441
|
+
}
|
442
|
+
},
|
443
|
+
|
444
|
+
/**
|
445
|
+
* '@' ('import' | 'keyframes' | 'charset' | 'page' | 'font-face')
|
446
|
+
*/
|
447
|
+
|
448
|
+
atrule: function() {
|
449
|
+
var captures;
|
450
|
+
if (captures = /^@(import|(?:-(\w+)-)?keyframes|charset|font-face|page) */.exec(this.str)) {
|
451
|
+
this.skip(captures);
|
452
|
+
var vendor = captures[2]
|
453
|
+
, type = captures[1];
|
454
|
+
if (vendor) type = 'keyframes';
|
455
|
+
return new Token(type, vendor);
|
456
|
+
}
|
457
|
+
},
|
458
|
+
|
459
|
+
/**
|
460
|
+
* '//' *
|
461
|
+
*/
|
462
|
+
|
463
|
+
comment: function() {
|
464
|
+
// Single line
|
465
|
+
if ('/' == this.str[0] && '/' == this.str[1]) {
|
466
|
+
var end = this.str.indexOf('\n');
|
467
|
+
if (-1 == end) end = this.str.length;
|
468
|
+
this.skip(end);
|
469
|
+
return this.advance();
|
470
|
+
}
|
471
|
+
|
472
|
+
// Multi-line
|
473
|
+
if ('/' == this.str[0] && '*' == this.str[1]) {
|
474
|
+
var end = this.str.indexOf('*/');
|
475
|
+
if (-1 == end) end = this.str.length;
|
476
|
+
var str = this.str.substr(0, end + 2)
|
477
|
+
, lines = str.split('\n').length - 1
|
478
|
+
, suppress = true;
|
479
|
+
this.lineno += lines;
|
480
|
+
this.skip(end + 2);
|
481
|
+
// output
|
482
|
+
if ('!' == str[2]) {
|
483
|
+
str = str.replace('*!', '*');
|
484
|
+
suppress = false;
|
485
|
+
}
|
486
|
+
return new Token('comment', new nodes.Comment(str, suppress));
|
487
|
+
}
|
488
|
+
},
|
489
|
+
|
490
|
+
/**
|
491
|
+
* 'true' | 'false'
|
492
|
+
*/
|
493
|
+
|
494
|
+
boolean: function() {
|
495
|
+
var captures;
|
496
|
+
if (captures = /^(true|false)\b( *)/.exec(this.str)) {
|
497
|
+
var val = nodes.Boolean('true' == captures[1]);
|
498
|
+
this.skip(captures);
|
499
|
+
var tok = new Token('boolean', val);
|
500
|
+
tok.space = captures[2];
|
501
|
+
return tok;
|
502
|
+
}
|
503
|
+
},
|
504
|
+
|
505
|
+
/**
|
506
|
+
* -?[a-zA-Z$] [-\w\d$]* '('
|
507
|
+
*/
|
508
|
+
|
509
|
+
function: function() {
|
510
|
+
var captures;
|
511
|
+
if (captures = /^(-?[a-zA-Z$][-\w\d$]*)\(( *)/.exec(this.str)) {
|
512
|
+
var name = captures[1];
|
513
|
+
this.skip(captures);
|
514
|
+
this.isURL = 'url' == name;
|
515
|
+
var tok = new Token('function', new nodes.Ident(name));
|
516
|
+
tok.space = captures[2];
|
517
|
+
return tok;
|
518
|
+
}
|
519
|
+
},
|
520
|
+
|
521
|
+
/**
|
522
|
+
* -?[_a-zA-Z$] [-\w\d$]*
|
523
|
+
*/
|
524
|
+
|
525
|
+
ident: function() {
|
526
|
+
var captures;
|
527
|
+
if (captures = /^(@)?(-?[_a-zA-Z$][-\w\d$]*)/.exec(this.str)) {
|
528
|
+
var at = captures[1]
|
529
|
+
, name = captures[2]
|
530
|
+
, id = new nodes.Ident(name);
|
531
|
+
this.skip(captures);
|
532
|
+
id.property = !! at;
|
533
|
+
return new Token('ident', id);
|
534
|
+
}
|
535
|
+
},
|
536
|
+
|
537
|
+
/**
|
538
|
+
* '\n' ' '+
|
539
|
+
*/
|
540
|
+
|
541
|
+
newline: function() {
|
542
|
+
var captures, re;
|
543
|
+
|
544
|
+
// we have established the indentation regexp
|
545
|
+
if (this.indentRe){
|
546
|
+
captures = this.indentRe.exec(this.str);
|
547
|
+
// figure out if we are using tabs or spaces
|
548
|
+
} else {
|
549
|
+
// try tabs
|
550
|
+
re = /^\n([\t]*) */;
|
551
|
+
captures = re.exec(this.str);
|
552
|
+
|
553
|
+
// nope, try spaces
|
554
|
+
if (captures && !captures[1].length) {
|
555
|
+
re = /^\n( *)/;
|
556
|
+
captures = re.exec(this.str);
|
557
|
+
}
|
558
|
+
|
559
|
+
// established
|
560
|
+
if (captures && captures[1].length) this.indentRe = re;
|
561
|
+
}
|
562
|
+
|
563
|
+
|
564
|
+
if (captures) {
|
565
|
+
var tok
|
566
|
+
, indents = captures[1].length;
|
567
|
+
|
568
|
+
this.skip(captures);
|
569
|
+
if (this.str[0] === ' ' || this.str[0] === '\t') {
|
570
|
+
throw new errors.SyntaxError('Invalid indentation. You can use tabs or spaces to indent, but not both.');
|
571
|
+
}
|
572
|
+
|
573
|
+
// Reset state
|
574
|
+
this.isVariable = false;
|
575
|
+
|
576
|
+
// Blank line
|
577
|
+
if ('\n' == this.str[0]) {
|
578
|
+
++this.lineno;
|
579
|
+
return this.advance();
|
580
|
+
}
|
581
|
+
|
582
|
+
// Outdent
|
583
|
+
if (this.indentStack.length && indents < this.indentStack[0]) {
|
584
|
+
while (this.indentStack.length && this.indentStack[0] > indents) {
|
585
|
+
this.stash.push(new Token('outdent'));
|
586
|
+
this.indentStack.shift();
|
587
|
+
}
|
588
|
+
tok = this.stash.pop();
|
589
|
+
// Indent
|
590
|
+
} else if (indents && indents != this.indentStack[0]) {
|
591
|
+
this.indentStack.unshift(indents);
|
592
|
+
tok = new Token('indent');
|
593
|
+
// Newline
|
594
|
+
} else {
|
595
|
+
tok = new Token('newline');
|
596
|
+
}
|
597
|
+
|
598
|
+
return tok;
|
599
|
+
}
|
600
|
+
},
|
601
|
+
|
602
|
+
/**
|
603
|
+
* '-'? (digit+ | digit* '.' digit+) unit
|
604
|
+
*/
|
605
|
+
|
606
|
+
unit: function() {
|
607
|
+
var captures;
|
608
|
+
if (captures = unit.exec(this.str)) {
|
609
|
+
this.skip(captures);
|
610
|
+
var n = parseFloat(captures[2]);
|
611
|
+
if ('-' == captures[1]) n = -n;
|
612
|
+
var node = new nodes.Unit(n, captures[3]);
|
613
|
+
return new Token('unit', node);
|
614
|
+
}
|
615
|
+
},
|
616
|
+
|
617
|
+
/**
|
618
|
+
* '"' [^"]+ '"' | "'"" [^']+ "'"
|
619
|
+
*/
|
620
|
+
|
621
|
+
string: function() {
|
622
|
+
var captures;
|
623
|
+
if (captures = /^("[^"]*"|'[^']*') */.exec(this.str)) {
|
624
|
+
var str = captures[1];
|
625
|
+
this.skip(captures);
|
626
|
+
str = str.slice(1,-1).replace(/\\n/g, '\n');
|
627
|
+
return new Token('string', new nodes.String(str));
|
628
|
+
}
|
629
|
+
},
|
630
|
+
|
631
|
+
/**
|
632
|
+
* #rrggbbaa | #rrggbb | #rgba | #rgb
|
633
|
+
*/
|
634
|
+
|
635
|
+
color: function() {
|
636
|
+
return this.rrggbbaa()
|
637
|
+
|| this.rrggbb()
|
638
|
+
|| this.rgba()
|
639
|
+
|| this.rgb()
|
640
|
+
},
|
641
|
+
|
642
|
+
/**
|
643
|
+
* #rgb
|
644
|
+
*/
|
645
|
+
|
646
|
+
rgb: function() {
|
647
|
+
var captures;
|
648
|
+
if (captures = /^#([a-fA-F0-9]{3}) */.exec(this.str)) {
|
649
|
+
this.skip(captures);
|
650
|
+
var rgb = captures[1]
|
651
|
+
, r = parseInt(rgb[0] + rgb[0], 16)
|
652
|
+
, g = parseInt(rgb[1] + rgb[1], 16)
|
653
|
+
, b = parseInt(rgb[2] + rgb[2], 16)
|
654
|
+
, color = new nodes.RGBA(r, g, b, 1);
|
655
|
+
color.raw = captures[0];
|
656
|
+
return new Token('color', color);
|
657
|
+
}
|
658
|
+
},
|
659
|
+
|
660
|
+
/**
|
661
|
+
* #rgba
|
662
|
+
*/
|
663
|
+
|
664
|
+
rgba: function() {
|
665
|
+
var captures;
|
666
|
+
if (captures = /^#([a-fA-F0-9]{4}) */.exec(this.str)) {
|
667
|
+
this.skip(captures);
|
668
|
+
var rgb = captures[1]
|
669
|
+
, r = parseInt(rgb[0] + rgb[0], 16)
|
670
|
+
, g = parseInt(rgb[1] + rgb[1], 16)
|
671
|
+
, b = parseInt(rgb[2] + rgb[2], 16)
|
672
|
+
, a = parseInt(rgb[3] + rgb[3], 16)
|
673
|
+
, color = new nodes.RGBA(r, g, b, a/255);
|
674
|
+
color.raw = captures[0];
|
675
|
+
return new Token('color', color);
|
676
|
+
}
|
677
|
+
},
|
678
|
+
|
679
|
+
/**
|
680
|
+
* #rrggbb
|
681
|
+
*/
|
682
|
+
|
683
|
+
rrggbb: function() {
|
684
|
+
var captures;
|
685
|
+
if (captures = /^#([a-fA-F0-9]{6}) */.exec(this.str)) {
|
686
|
+
this.skip(captures);
|
687
|
+
var rgb = captures[1]
|
688
|
+
, r = parseInt(rgb.substr(0, 2), 16)
|
689
|
+
, g = parseInt(rgb.substr(2, 2), 16)
|
690
|
+
, b = parseInt(rgb.substr(4, 2), 16)
|
691
|
+
, color = new nodes.RGBA(r, g, b, 1);
|
692
|
+
color.raw = captures[0];
|
693
|
+
return new Token('color', color);
|
694
|
+
}
|
695
|
+
},
|
696
|
+
|
697
|
+
/**
|
698
|
+
* #rrggbbaa
|
699
|
+
*/
|
700
|
+
|
701
|
+
rrggbbaa: function() {
|
702
|
+
var captures;
|
703
|
+
if (captures = /^#([a-fA-F0-9]{8}) */.exec(this.str)) {
|
704
|
+
this.skip(captures);
|
705
|
+
var rgb = captures[1]
|
706
|
+
, r = parseInt(rgb.substr(0, 2), 16)
|
707
|
+
, g = parseInt(rgb.substr(2, 2), 16)
|
708
|
+
, b = parseInt(rgb.substr(4, 2), 16)
|
709
|
+
, a = parseInt(rgb.substr(6, 2), 16)
|
710
|
+
, color = new nodes.RGBA(r, g, b, a/255);
|
711
|
+
color.raw = captures[0];
|
712
|
+
return new Token('color', color);
|
713
|
+
}
|
714
|
+
},
|
715
|
+
|
716
|
+
/**
|
717
|
+
* [^\n,;]+
|
718
|
+
*/
|
719
|
+
|
720
|
+
selector: function() {
|
721
|
+
var captures;
|
722
|
+
if (captures = /^[^{\n,]+/.exec(this.str)) {
|
723
|
+
var selector = captures[0];
|
724
|
+
this.skip(captures);
|
725
|
+
return new Token('selector', selector);
|
726
|
+
}
|
727
|
+
}
|
728
|
+
};
|