stylus-source 0.15.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/.DS_Store +0 -0
  2. data/README.md +3 -0
  3. data/lib/.DS_Store +0 -0
  4. data/lib/node_modules/cssom/.idea/CSSOM.iml +9 -0
  5. data/lib/node_modules/cssom/.idea/dictionaries/nv.xml +3 -0
  6. data/lib/node_modules/cssom/.idea/encodings.xml +5 -0
  7. data/lib/node_modules/cssom/.idea/misc.xml +17 -0
  8. data/lib/node_modules/cssom/.idea/modules.xml +9 -0
  9. data/lib/node_modules/cssom/.idea/projectCodeStyle.xml +82 -0
  10. data/lib/node_modules/cssom/.idea/vcs.xml +8 -0
  11. data/lib/node_modules/cssom/.idea/workspace.xml +467 -0
  12. data/lib/node_modules/cssom/.livereload +19 -0
  13. data/lib/node_modules/cssom/Jakefile +37 -0
  14. data/lib/node_modules/cssom/README.mdown +33 -0
  15. data/lib/node_modules/cssom/Rakefile +23 -0
  16. data/lib/node_modules/cssom/docs/.livereload +19 -0
  17. data/lib/node_modules/cssom/docs/bar.css +3 -0
  18. data/lib/node_modules/cssom/docs/demo.css +0 -0
  19. data/lib/node_modules/cssom/docs/foo.css +4 -0
  20. data/lib/node_modules/cssom/docs/parse.html +170 -0
  21. data/lib/node_modules/cssom/docs/parse2.html +431 -0
  22. data/lib/node_modules/cssom/index.html +100 -0
  23. data/lib/node_modules/cssom/lib/CSSImportRule.js +34 -0
  24. data/lib/node_modules/cssom/lib/CSSMediaRule.js +38 -0
  25. data/lib/node_modules/cssom/lib/CSSOM.js +3 -0
  26. data/lib/node_modules/cssom/lib/CSSRule.js +38 -0
  27. data/lib/node_modules/cssom/lib/CSSStyleDeclaration.js +130 -0
  28. data/lib/node_modules/cssom/lib/CSSStyleRule.js +187 -0
  29. data/lib/node_modules/cssom/lib/CSSStyleSheet.js +85 -0
  30. data/lib/node_modules/cssom/lib/MediaList.js +61 -0
  31. data/lib/node_modules/cssom/lib/StyleSheet.js +15 -0
  32. data/lib/node_modules/cssom/lib/clone.js +69 -0
  33. data/lib/node_modules/cssom/lib/index.js +10 -0
  34. data/lib/node_modules/cssom/lib/parse.js +195 -0
  35. data/lib/node_modules/cssom/media.html +17 -0
  36. data/lib/node_modules/cssom/package.json +30 -0
  37. data/lib/node_modules/cssom/plugins/toHTML.js +32 -0
  38. data/lib/node_modules/cssom/server/index.html +22 -0
  39. data/lib/node_modules/cssom/server/index.js +21 -0
  40. data/lib/node_modules/cssom/shorthands.html +21 -0
  41. data/lib/node_modules/cssom/test/CSSStyleDeclaration.test.js +35 -0
  42. data/lib/node_modules/cssom/test/CSSStyleRule.test.js +12 -0
  43. data/lib/node_modules/cssom/test/CSSStyleSheet.test.js +16 -0
  44. data/lib/node_modules/cssom/test/MediaList.test.js +21 -0
  45. data/lib/node_modules/cssom/test/clone.test.js +38 -0
  46. data/lib/node_modules/cssom/test/fixtures/dummy.css +3 -0
  47. data/lib/node_modules/cssom/test/helper.js +97 -0
  48. data/lib/node_modules/cssom/test/index.html +42 -0
  49. data/lib/node_modules/cssom/test/parse.test.js +346 -0
  50. data/lib/node_modules/cssom/test/vendor/qunit.css +189 -0
  51. data/lib/node_modules/cssom/test/vendor/qunit.js +1341 -0
  52. data/lib/node_modules/growl/History.md +16 -0
  53. data/lib/node_modules/growl/Readme.md +74 -0
  54. data/lib/node_modules/growl/lib/growl.js +82 -0
  55. data/lib/node_modules/growl/package.json +6 -0
  56. data/lib/node_modules/growl/test.js +17 -0
  57. data/lib/stylus/colors.js +156 -0
  58. data/lib/stylus/convert/css.js +130 -0
  59. data/lib/stylus/errors.js +58 -0
  60. data/lib/stylus/functions/image.js +120 -0
  61. data/lib/stylus/functions/index.js +722 -0
  62. data/lib/stylus/functions/index.styl +123 -0
  63. data/lib/stylus/functions/url.js +98 -0
  64. data/lib/stylus/lexer.js +728 -0
  65. data/lib/stylus/middleware.js +223 -0
  66. data/lib/stylus/nodes/arguments.js +65 -0
  67. data/lib/stylus/nodes/binop.js +54 -0
  68. data/lib/stylus/nodes/block.js +99 -0
  69. data/lib/stylus/nodes/boolean.js +103 -0
  70. data/lib/stylus/nodes/call.js +57 -0
  71. data/lib/stylus/nodes/charset.js +42 -0
  72. data/lib/stylus/nodes/comment.js +32 -0
  73. data/lib/stylus/nodes/each.js +56 -0
  74. data/lib/stylus/nodes/expression.js +168 -0
  75. data/lib/stylus/nodes/fontface.js +55 -0
  76. data/lib/stylus/nodes/function.js +104 -0
  77. data/lib/stylus/nodes/group.js +79 -0
  78. data/lib/stylus/nodes/hsla.js +256 -0
  79. data/lib/stylus/nodes/ident.js +127 -0
  80. data/lib/stylus/nodes/if.js +55 -0
  81. data/lib/stylus/nodes/import.js +30 -0
  82. data/lib/stylus/nodes/index.js +52 -0
  83. data/lib/stylus/nodes/jsliteral.js +32 -0
  84. data/lib/stylus/nodes/keyframes.js +78 -0
  85. data/lib/stylus/nodes/literal.js +92 -0
  86. data/lib/stylus/nodes/media.js +42 -0
  87. data/lib/stylus/nodes/node.js +209 -0
  88. data/lib/stylus/nodes/null.js +72 -0
  89. data/lib/stylus/nodes/page.js +43 -0
  90. data/lib/stylus/nodes/params.js +72 -0
  91. data/lib/stylus/nodes/property.js +72 -0
  92. data/lib/stylus/nodes/return.js +44 -0
  93. data/lib/stylus/nodes/rgba.js +335 -0
  94. data/lib/stylus/nodes/root.js +50 -0
  95. data/lib/stylus/nodes/selector.js +57 -0
  96. data/lib/stylus/nodes/string.js +120 -0
  97. data/lib/stylus/nodes/ternary.js +51 -0
  98. data/lib/stylus/nodes/unaryop.js +46 -0
  99. data/lib/stylus/nodes/unit.js +207 -0
  100. data/lib/stylus/parser.js +1514 -0
  101. data/lib/stylus/renderer.js +157 -0
  102. data/lib/stylus/source.rb +7 -0
  103. data/lib/stylus/stack/frame.js +66 -0
  104. data/lib/stylus/stack/index.js +146 -0
  105. data/lib/stylus/stack/scope.js +53 -0
  106. data/lib/stylus/stylus.js +102 -0
  107. data/lib/stylus/token.js +53 -0
  108. data/lib/stylus/utils.js +237 -0
  109. data/lib/stylus/visitor/compiler.js +472 -0
  110. data/lib/stylus/visitor/evaluator.js +1070 -0
  111. data/lib/stylus/visitor/index.js +31 -0
  112. data/stylus-source.gemspec +15 -0
  113. metadata +158 -0
@@ -0,0 +1,58 @@
1
+
2
+ /*!
3
+ * Stylus - errors
4
+ * Copyright(c) 2010 LearnBoost <dev@learnboost.com>
5
+ * MIT Licensed
6
+ */
7
+
8
+ /**
9
+ * Expose constructors.
10
+ */
11
+
12
+ exports.ParseError = ParseError;
13
+ exports.SyntaxError = SyntaxError;
14
+
15
+ /**
16
+ * Inherit from `Error.prototype`.
17
+ */
18
+
19
+ SyntaxError.prototype.__proto__ = Error.prototype;
20
+
21
+ /**
22
+ * Initialize a new `ParseError` with the given `msg`.
23
+ *
24
+ * @param {String} msg
25
+ * @api private
26
+ */
27
+
28
+ function ParseError(msg) {
29
+ this.name = 'ParseError';
30
+ this.message = msg;
31
+ Error.captureStackTrace(this, ParseError);
32
+ }
33
+
34
+ /**
35
+ * Inherit from `Error.prototype`.
36
+ */
37
+
38
+ ParseError.prototype.__proto__ = Error.prototype;
39
+
40
+ /**
41
+ * Initialize a new `SyntaxError` with the given `msg`.
42
+ *
43
+ * @param {String} msg
44
+ * @api private
45
+ */
46
+
47
+ function SyntaxError(msg) {
48
+ this.name = 'SyntaxError';
49
+ this.message = msg;
50
+ Error.captureStackTrace(this, ParseError);
51
+ }
52
+
53
+ /**
54
+ * Inherit from `Error.prototype`.
55
+ */
56
+
57
+ SyntaxError.prototype.__proto__ = Error.prototype;
58
+
@@ -0,0 +1,120 @@
1
+
2
+
3
+ /*!
4
+ * Stylus - plugin - url
5
+ * Copyright(c) 2010 LearnBoost <dev@learnboost.com>
6
+ * MIT Licensed
7
+ */
8
+
9
+ /**
10
+ * Module dependencies.
11
+ */
12
+
13
+ var utils = require('../utils')
14
+ , nodes = require('../nodes')
15
+ , fs = require('fs');
16
+
17
+ /**
18
+ * Initialize a new `Image` with the given `ctx` and `path.
19
+ *
20
+ * @param {Evaluator} ctx
21
+ * @param {String} path
22
+ * @api private
23
+ */
24
+
25
+ var Image = module.exports = function Image(ctx, path) {
26
+ this.ctx = ctx;
27
+ this.path = utils.lookup(path, ctx.paths);
28
+ if (!this.path) throw new Error('failed to locate file ' + path);
29
+ };
30
+
31
+ /**
32
+ * Open the image for reading.
33
+ *
34
+ * @api private
35
+ */
36
+
37
+ Image.prototype.open = function(){
38
+ this.fd = fs.openSync(this.path, 'r');
39
+ };
40
+
41
+ /**
42
+ * Close the file.
43
+ *
44
+ * @api private
45
+ */
46
+
47
+ Image.prototype.close = function(){
48
+ if (this.fd) fs.closeSync(this.fd);
49
+ };
50
+
51
+ /**
52
+ * Return the type of image, supports:
53
+ *
54
+ * - gif
55
+ * - png
56
+ * - jpeg
57
+ *
58
+ * @return {String}
59
+ * @api private
60
+ */
61
+
62
+ Image.prototype.type = function(){
63
+ var type
64
+ , buf = new Buffer(4);
65
+
66
+ fs.readSync(this.fd, buf, 0, 4, 0);
67
+
68
+ // GIF
69
+ if (0x47 == buf[0] && 0x49 == buf[1] && 0x46 == buf[2]) type = 'gif';
70
+
71
+ // PNG
72
+ else if (0x50 == buf[1] && 0x4E == buf[2] && 0x47 == buf[3]) type = 'png';
73
+
74
+ // JPEG
75
+ else if (0xff == buf[0] && 0xd8 == buf[1]) type = 'jpeg';
76
+
77
+ return type;
78
+ };
79
+
80
+ /**
81
+ * Return image dimensions `[width, height]`.
82
+ *
83
+ * @return {Array}
84
+ * @api private
85
+ */
86
+
87
+ Image.prototype.size = function(){
88
+ var width
89
+ , height
90
+ , type = this.type();
91
+
92
+ function uint16(b) { return b[1] << 8 | b[0]; }
93
+ function uint32(b) { return b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3]; }
94
+
95
+ // Determine dimensions
96
+ switch (type) {
97
+ case 'jpeg':
98
+ throw new Error('image-size() jpeg support not yet implemented');
99
+ break;
100
+ case 'png':
101
+ var buf = new Buffer(8);
102
+ // IHDR chunk width / height uint32_t big-endian
103
+ fs.readSync(this.fd, buf, 0, 8, 16);
104
+ width = uint32(buf);
105
+ height = uint32(buf.slice(4, 8));
106
+ break;
107
+ case 'gif':
108
+ var buf = new Buffer(4);
109
+ // width / height uint16_t little-endian
110
+ fs.readSync(this.fd, buf, 0, 4, 6);
111
+ width = uint16(buf);
112
+ height = uint16(buf.slice(2, 4));
113
+ break;
114
+ }
115
+
116
+ if ('number' != typeof width) throw new Error('failed to find width of "' + this.path + '"');
117
+ if ('number' != typeof height) throw new Error('failed to find height of "' + this.path + '"');
118
+
119
+ return [width, height];
120
+ };
@@ -0,0 +1,722 @@
1
+
2
+ /*!
3
+ * Stylus - Evaluator - built-in functions
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
+ , utils = require('../utils')
15
+ , Image = require('./image');
16
+
17
+ /**
18
+ * Color component name map.
19
+ */
20
+
21
+ var componentMap = {
22
+ red: 'r'
23
+ , green: 'g'
24
+ , blue: 'b'
25
+ , alpha: 'a'
26
+ , hue: 'h'
27
+ , saturation: 's'
28
+ , lightness: 'l'
29
+ };
30
+
31
+ /**
32
+ * Color component unit type map.
33
+ */
34
+
35
+ var unitMap = {
36
+ hue: 'deg'
37
+ , saturation: '%'
38
+ , lightness: '%'
39
+ };
40
+
41
+ /**
42
+ * Color type map.
43
+ */
44
+
45
+ var typeMap = {
46
+ red: 'rgba'
47
+ , blue: 'rgba'
48
+ , green: 'rgba'
49
+ , alpha: 'rgba'
50
+ , hue: 'hsla'
51
+ , saturation: 'hsla'
52
+ , lightness: 'hsla'
53
+ };
54
+
55
+ /**
56
+ * Convert the given `color` to an `HSLA` node,
57
+ * or h,s,l,a component values.
58
+ *
59
+ * Examples:
60
+ *
61
+ * hsla(10deg, 50%, 30%, 0.5)
62
+ * // => HSLA
63
+ *
64
+ * hsla(#ffcc00)
65
+ * // => HSLA
66
+ *
67
+ * @param {RGBA|HSLA|Unit} hue
68
+ * @param {Unit} saturation
69
+ * @param {Unit} lightness
70
+ * @param {Unit} alpha
71
+ * @return {HSLA}
72
+ * @api public
73
+ */
74
+
75
+ exports.hsla = function hsla(hue, saturation, lightness, alpha){
76
+ switch (arguments.length) {
77
+ case 1:
78
+ utils.assertColor(hue);
79
+ return hue.hsla;
80
+ default:
81
+ utils.assertType(hue, 'unit', 'hue');
82
+ utils.assertType(saturation, 'unit', 'saturation');
83
+ utils.assertType(lightness, 'unit', 'lightness');
84
+ utils.assertType(alpha, 'unit', 'alpha');
85
+ return new nodes.HSLA(
86
+ hue.val
87
+ , saturation.val
88
+ , lightness.val
89
+ , alpha.val);
90
+ }
91
+ };
92
+
93
+ /**
94
+ * Convert the given `color` to an `HSLA` node,
95
+ * or h,s,l component values.
96
+ *
97
+ * Examples:
98
+ *
99
+ * hsl(10, 50, 30)
100
+ * // => HSLA
101
+ *
102
+ * hsl(#ffcc00)
103
+ * // => HSLA
104
+ *
105
+ * @param {Unit|HSLA|RGBA} hue
106
+ * @param {Unit} saturation
107
+ * @param {Unit} lightness
108
+ * @return {HSLA}
109
+ * @api public
110
+ */
111
+
112
+ exports.hsl = function hsl(hue, saturation, lightness){
113
+ if (1 == arguments.length) {
114
+ utils.assertColor(hue, 'color');
115
+ return hue.hsla;
116
+ } else {
117
+ return exports.hsla(
118
+ hue
119
+ , saturation
120
+ , lightness
121
+ , new nodes.Unit(1));
122
+ }
123
+ };
124
+
125
+ /**
126
+ * Return type of `node`.
127
+ *
128
+ * Examples:
129
+ *
130
+ * type(12)
131
+ * // => 'unit'
132
+ *
133
+ * type(#fff)
134
+ * // => 'color'
135
+ *
136
+ * type(type)
137
+ * // => 'function'
138
+ *
139
+ * type(unbound)
140
+ * typeof(unbound)
141
+ * type-of(unbound)
142
+ * // => 'ident'
143
+ *
144
+ * @param {Node} node
145
+ * @return {String}
146
+ * @api public
147
+ */
148
+
149
+ exports.type =
150
+ exports.typeof =
151
+ exports['type-of'] = function type(node){
152
+ utils.assertPresent(node, 'expression');
153
+ var type = node.nodeName;
154
+ return new nodes.String(type);
155
+ };
156
+
157
+ /**
158
+ * Return component `name` for the given `color`.
159
+ *
160
+ * @param {RGBA|HSLA} color
161
+ * @param {String} na,e
162
+ * @return {Unit}
163
+ * @api public
164
+ */
165
+
166
+ exports.component = function component(color, name) {
167
+ utils.assertColor(color, 'color');
168
+ utils.assertString(name, 'name');
169
+ var name = name.string
170
+ , unit = unitMap[name]
171
+ , type = typeMap[name]
172
+ , name = componentMap[name];
173
+ if (!name) throw new Error('invalid color component "' + name + '"');
174
+ return new nodes.Unit(color[type][name], unit);
175
+ };
176
+
177
+ /**
178
+ * Return the red component of the given `color`.
179
+ *
180
+ * Examples:
181
+ *
182
+ * red(#c00)
183
+ * // => 204
184
+ *
185
+ * @param {RGBA|HSLA} color
186
+ * @return {Unit}
187
+ * @api public
188
+ */
189
+
190
+ exports.red = function red(color){
191
+ return exports.component(color, new nodes.String('red'));
192
+ };
193
+
194
+ /**
195
+ * Return the green component of the given `color`.
196
+ *
197
+ * Examples:
198
+ *
199
+ * green(#0c0)
200
+ * // => 204
201
+ *
202
+ * @param {RGBA|HSLA} color
203
+ * @return {Unit}
204
+ * @api public
205
+ */
206
+
207
+ exports.green = function green(color){
208
+ return exports.component(color, new nodes.String('green'));
209
+ };
210
+
211
+ /**
212
+ * Return the blue component of the given `color`.
213
+ *
214
+ * Examples:
215
+ *
216
+ * blue(#00c)
217
+ * // => 204
218
+ *
219
+ * @param {RGBA|HSLA} color
220
+ * @return {Unit}
221
+ * @api public
222
+ */
223
+
224
+ exports.blue = function blue(color){
225
+ return exports.component(color, new nodes.String('blue'));
226
+ };
227
+
228
+ /**
229
+ * Return a `RGBA` from the r,g,b,a channels.
230
+ *
231
+ * Examples:
232
+ *
233
+ * rgba(255,0,0,0.5)
234
+ * // => rgba(255,0,0,0.5)
235
+ *
236
+ * rgba(255,0,0,1)
237
+ * // => #ff0000
238
+ *
239
+ * rgba(#ffcc00, 0.5)
240
+ * // rgba(255,204,0,0.5)
241
+ *
242
+ * @param {Unit|RGBA|HSLA} red
243
+ * @param {Unit} green
244
+ * @param {Unit} blue
245
+ * @param {Unit} alpha
246
+ * @return {RGBA}
247
+ * @api public
248
+ */
249
+
250
+ exports.rgba = function rgba(red, green, blue, alpha){
251
+ switch (arguments.length) {
252
+ case 1:
253
+ utils.assertColor(red);
254
+ var color = red.rgba;
255
+ return new nodes.RGBA(
256
+ color.r
257
+ , color.g
258
+ , color.b
259
+ , color.a);
260
+ case 2:
261
+ utils.assertColor(red);
262
+ var color = red.rgba;
263
+ utils.assertType(green, 'unit', 'alpha');
264
+ return new nodes.RGBA(
265
+ color.r
266
+ , color.g
267
+ , color.b
268
+ , green.val);
269
+ default:
270
+ utils.assertType(red, 'unit', 'red');
271
+ utils.assertType(green, 'unit', 'green');
272
+ utils.assertType(blue, 'unit', 'blue');
273
+ utils.assertType(alpha, 'unit', 'alpha');
274
+ return new nodes.RGBA(
275
+ red.val
276
+ , green.val
277
+ , blue.val
278
+ , alpha.val);
279
+ }
280
+ };
281
+
282
+ /**
283
+ * Return a `RGBA` from the r,g,b channels.
284
+ *
285
+ * Examples:
286
+ *
287
+ * rgb(255,204,0)
288
+ * // => #ffcc00
289
+ *
290
+ * rgb(#fff)
291
+ * // => #fff
292
+ *
293
+ * @param {Unit|RGBA|HSLA} red
294
+ * @param {Unit} green
295
+ * @param {Unit} blue
296
+ * @return {RGBA}
297
+ * @api public
298
+ */
299
+
300
+ exports.rgb = function rgb(red, green, blue){
301
+ switch (arguments.length) {
302
+ case 1:
303
+ utils.assertColor(red);
304
+ var color = red.rgba;
305
+ return new nodes.RGBA(
306
+ color.r
307
+ , color.g
308
+ , color.b
309
+ , 1);
310
+ default:
311
+ return exports.rgba(
312
+ red
313
+ , green
314
+ , blue
315
+ , new nodes.Unit(1));
316
+ }
317
+ };
318
+
319
+ /**
320
+ * Unquote the given `str`.
321
+ *
322
+ * Examples:
323
+ *
324
+ * unquote("sans-serif")
325
+ * // => sans-serif
326
+ *
327
+ * unquote(sans-serif)
328
+ * // => sans-serif
329
+ *
330
+ * @param {String|Ident} string
331
+ * @return {Literal}
332
+ * @api public
333
+ */
334
+
335
+ exports.unquote = function unquote(string){
336
+ utils.assertString(string, 'string');
337
+ return new nodes.Literal(string.string);
338
+ };
339
+
340
+ /**
341
+ * Assign `type` to the given `unit` or return `unit`'s type.
342
+ *
343
+ * @param {Unit} unit
344
+ * @param {String|Ident} type
345
+ * @return {Unit}
346
+ * @api public
347
+ */
348
+
349
+ exports.unit = function unit(unit, type){
350
+ utils.assertType(unit, 'unit', 'unit');
351
+
352
+ // Assign
353
+ if (type) {
354
+ utils.assertString(type, 'type');
355
+ return new nodes.Unit(unit.val, type.string);
356
+ } else {
357
+ return new nodes.String(unit.type || '');
358
+ }
359
+ };
360
+
361
+ /**
362
+ * Lookup variable `name` or return Null.
363
+ *
364
+ * @param {String} name
365
+ * @return {Mixed}
366
+ * @api public
367
+ */
368
+
369
+ exports.lookup = function lookup(name){
370
+ utils.assertType(name, 'string', 'name');
371
+ var node = this.lookup(name.val);
372
+ if (!node) return nodes.null;
373
+ return this.visit(node);
374
+ };
375
+
376
+ /**
377
+ * Perform `op` on the `left` and `right` operands.
378
+ *
379
+ * @param {String} op
380
+ * @param {Node} left
381
+ * @param {Node} right
382
+ * @return {Node}
383
+ * @api public
384
+ */
385
+
386
+ exports.operate = function operate(op, left, right){
387
+ utils.assertType(op, 'string', 'op');
388
+ utils.assertPresent(left, 'left');
389
+ utils.assertPresent(right, 'right');
390
+ return left.operate(op.val, right);
391
+ };
392
+
393
+ /**
394
+ * Test if `val` matches the given `pattern`.
395
+ *
396
+ * Examples:
397
+ *
398
+ * match('^foo(bar)?', foo)
399
+ * match('^foo(bar)?', foobar)
400
+ * match('^foo(bar)?', 'foo')
401
+ * match('^foo(bar)?', 'foobar')
402
+ * // => true
403
+ *
404
+ * match('^foo(bar)?', 'bar')
405
+ * // => false
406
+ *
407
+ * @param {String} pattern
408
+ * @param {String|Ident} val
409
+ * @return {Boolean}
410
+ * @api public
411
+ */
412
+
413
+ exports.match = function match(pattern, val){
414
+ utils.assertType(pattern, 'string', 'pattern');
415
+ utils.assertString(val, 'val');
416
+ var re = new RegExp(pattern.val);
417
+ return nodes.Boolean(re.test(val.string));
418
+ };
419
+
420
+ /**
421
+ * Return length of the given `expr`.
422
+ *
423
+ * @param {Expression} expr
424
+ * @return {Unit}
425
+ * @api public
426
+ */
427
+
428
+ (exports.length = function length(expr){
429
+ if (expr) {
430
+ if (expr.nodes) {
431
+ return new nodes.Unit(utils.unwrap(expr).nodes.length);
432
+ } else {
433
+ return new nodes.Unit(1);
434
+ }
435
+ }
436
+ return new nodes.Unit(0);
437
+ }).raw = true;
438
+
439
+ /**
440
+ * Inspect the given `expr`.
441
+ *
442
+ * @param {Expression} expr
443
+ * @api public
444
+ */
445
+
446
+ (exports.p = function p(expr){
447
+ expr = utils.unwrap(expr);
448
+ console.log('\033[90minspect:\033[0m %s'
449
+ , expr.toString().replace(/^\(|\)$/g, ''));
450
+ return nodes.null;
451
+ }).raw = true;
452
+
453
+ /**
454
+ * Throw an error with the given `msg`.
455
+ *
456
+ * @param {String} msg
457
+ * @api public
458
+ */
459
+
460
+ exports.error = function error(msg){
461
+ utils.assertType(msg, 'string', 'msg');
462
+ throw new Error(msg.val);
463
+ };
464
+
465
+ /**
466
+ * Warn with the given `msg` prefixed by "Warning: ".
467
+ *
468
+ * @param {String} msg
469
+ * @api public
470
+ */
471
+
472
+ exports.warn = function warn(msg){
473
+ utils.assertType(msg, 'string', 'msg');
474
+ console.warn('Warning: %s', msg.val);
475
+ return nodes.null;
476
+ };
477
+
478
+ /**
479
+ * Output stack trace.
480
+ *
481
+ * @api public
482
+ */
483
+
484
+ exports.trace = function trace(){
485
+ console.log(this.stack);
486
+ return nodes.null;
487
+ };
488
+
489
+ /**
490
+ * Push the given args to `expr`.
491
+ *
492
+ * @param {Expression} expr
493
+ * @param {Node} ...
494
+ * @return {Unit}
495
+ * @api public
496
+ */
497
+
498
+ (exports.push = exports.append = function(expr){
499
+ expr = utils.unwrap(expr);
500
+ for (var i = 1, len = arguments.length; i < len; ++i) {
501
+ expr.nodes.push(utils.unwrap(arguments[i]));
502
+ }
503
+ return new nodes.Unit(expr.nodes.length);
504
+ }).raw = true;
505
+
506
+ /**
507
+ * Unshift the given args to `expr`.
508
+ *
509
+ * @param {Expression} expr
510
+ * @param {Node} ...
511
+ * @return {Unit}
512
+ * @api public
513
+ */
514
+
515
+ (exports.unshift = exports.prepend = function(expr){
516
+ expr = utils.unwrap(expr);
517
+ for (var i = 1, len = arguments.length; i < len; ++i) {
518
+ expr.nodes.unshift(utils.unwrap(arguments[i]));
519
+ }
520
+ return new nodes.Unit(expr.nodes.length);
521
+ }).raw = true;
522
+
523
+ /**
524
+ * Return a `Literal` with the given `fmt`, and
525
+ * variable number of arguments.
526
+ *
527
+ * @param {String} fmt
528
+ * @param {Node} ...
529
+ * @return {Literal}
530
+ * @api public
531
+ */
532
+
533
+ (exports.s = function s(fmt){
534
+ fmt = utils.unwrap(fmt).nodes[0];
535
+ utils.assertString(fmt);
536
+ var self = this
537
+ , str = fmt.string
538
+ , args = arguments
539
+ , i = 1;
540
+
541
+ // format
542
+ str = str.replace(/%(s|d)/g, function(_, specifier){
543
+ var arg = args[i++] || nodes.null;
544
+ switch (specifier) {
545
+ case 's':
546
+ return new Compiler(arg, self.options).compile();
547
+ case 'd':
548
+ arg = utils.unwrap(arg).first;
549
+ if ('unit' != arg.nodeName) throw new Error('%d requires a unit');
550
+ return arg.val;
551
+ }
552
+ });
553
+
554
+ return new nodes.Literal(str);
555
+ }).raw = true;
556
+
557
+ /**
558
+ * Return the opposites of the given `positions`.
559
+ *
560
+ * Examples:
561
+ *
562
+ * opposite-position(top left)
563
+ * // => bottom right
564
+ *
565
+ * @param {Expression} positions
566
+ * @return {Expression}
567
+ * @api public
568
+ */
569
+
570
+ (exports['opposite-position'] = function oppositePosition(positions){
571
+ var expr = new nodes.Expression;
572
+ utils.unwrap(positions).nodes.forEach(function(pos, i){
573
+ utils.assertString(pos, 'position ' + i);
574
+ pos = (function(){ switch (pos.string) {
575
+ case 'top': return 'bottom';
576
+ case 'bottom': return 'top';
577
+ case 'left': return 'right';
578
+ case 'right': return 'left';
579
+ default: throw new Error('invalid position ' + pos);
580
+ }})();
581
+ expr.push(new nodes.Literal(pos));
582
+ });
583
+ return expr;
584
+ }).raw = true;
585
+
586
+ /**
587
+ * Return the width and height of the given `img` path.
588
+ *
589
+ * Examples:
590
+ *
591
+ * image-size('foo.png')
592
+ * // => 200px 100px
593
+ *
594
+ * image-size('foo.png')[0]
595
+ * // => 200px
596
+ *
597
+ * image-size('foo.png')[1]
598
+ * // => 100px
599
+ *
600
+ * @param {String} img
601
+ * @return {Expression}
602
+ * @api public
603
+ */
604
+
605
+ exports['image-size'] = function imageSize(img) {
606
+ utils.assertType(img, 'string', 'img');
607
+ var img = new Image(this, img.string);
608
+
609
+ // Read size
610
+ img.open();
611
+ var size = img.size();
612
+ img.close();
613
+
614
+ // Return (w h)
615
+ var expr = new nodes.Expression;
616
+ expr.push(new nodes.Unit(size[0], 'px'));
617
+ expr.push(new nodes.Unit(size[1], 'px'));
618
+
619
+ return expr;
620
+ };
621
+
622
+ /**
623
+ * Apply Math `fn` to `n`.
624
+ *
625
+ * @param {Unit} n
626
+ * @param {String} fn
627
+ * @return {Unit}
628
+ * @api private
629
+ */
630
+
631
+ exports['-math'] = function math(n, fn){
632
+ return new nodes.Unit(Math[fn.string](n.val), n.type);
633
+ };
634
+
635
+ /**
636
+ * Get Math `prop`.
637
+ *
638
+ * @param {String} prop
639
+ * @return {Unit}
640
+ * @api private
641
+ */
642
+
643
+ exports['-math-prop'] = function math(prop){
644
+ return new nodes.Unit(Math[prop.string]);
645
+ };
646
+
647
+ /**
648
+ * Buffer the given js `str`.
649
+ *
650
+ * @param {String} str
651
+ * @return {JSLiteral}
652
+ * @api private
653
+ */
654
+
655
+ exports.js = function js(str){
656
+ utils.assertString(str, 'str');
657
+ return new nodes.JSLiteral(str.val);
658
+ };
659
+
660
+ /**
661
+ * Adjust HSL `color` `prop` by `amount`.
662
+ *
663
+ * @param {RGBA|HSLA} color
664
+ * @param {String} prop
665
+ * @param {Unit} amount
666
+ * @return {RGBA}
667
+ * @api private
668
+ */
669
+
670
+ exports['-adjust'] = function adjust(color, prop, amount){
671
+ var hsl = color.hsla.clone();
672
+ prop = { hue: 'h', saturation: 's', lightness: 'l' }[prop.string];
673
+ if (!prop) throw new Error('invalid adjustment property');
674
+ var val = amount.val;
675
+ if ('%' == amount.type){
676
+ val = 'l' == prop && val > 0
677
+ ? (100 - hsl[prop]) * val / 100
678
+ : hsl[prop] * (val / 100);
679
+ }
680
+ hsl[prop] += val;
681
+ return hsl.rgba;
682
+ };
683
+
684
+ /**
685
+ * Return a clone of the given `expr`.
686
+ *
687
+ * @param {Expression} expr
688
+ * @return {Node}
689
+ * @api public
690
+ */
691
+
692
+ (exports.clone = function clone(expr){
693
+ utils.assertPresent(expr, 'expr');
694
+ return expr.clone();
695
+ }).raw = true;
696
+
697
+ /**
698
+ * Add property `name` with the given `expr`
699
+ * to the mixin-able block.
700
+ *
701
+ * @param {String|Ident|Literal} name
702
+ * @param {Expression} expr
703
+ * @return {Property}
704
+ * @api public
705
+ */
706
+
707
+ (exports['add-property'] = function addProperty(name, expr){
708
+ utils.assertType(name, 'expression', 'name');
709
+ name = utils.unwrap(name).first;
710
+ utils.assertString(name, 'name');
711
+ utils.assertType(expr, 'expression', 'expr');
712
+ var prop = new nodes.Property([name], expr);
713
+ var block = this.closestBlock;
714
+
715
+ var len = block.nodes.length
716
+ , head = block.nodes.slice(0, block.index)
717
+ , tail = block.nodes.slice(block.index++, len);
718
+ head.push(prop);
719
+ block.nodes = head.concat(tail);
720
+
721
+ return prop;
722
+ }).raw = true;