Comparing version 0.7.1 to 0.7.2
0.7.2 / 2011-03-08 | ||
================== | ||
* Added `isnt` operator, same as `is not`, and `!=` | ||
* Added support for dynamic `@import` expressions | ||
* Added `@import` index resolution support | ||
* Added `light()` / `dark()` BIFs | ||
* Added `compress` option for connect middleware [disfated] | ||
* Changed; most built-in functions defined in stylus (`./lib/functions/index.styl`) | ||
* Fixed dynamic expressions in `url()`. Closes #105 | ||
0.7.1 / 2011-03-07 | ||
@@ -3,0 +14,0 @@ ================== |
@@ -17,2 +17,26 @@ | ||
/** | ||
* Color component name map. | ||
*/ | ||
var componentMap = { | ||
red: 'r' | ||
, green: 'g' | ||
, blue: 'b' | ||
, alpha: 'a' | ||
, hue: 'h' | ||
, saturation: 's' | ||
, lightness: 'l' | ||
}; | ||
/** | ||
* Color component type map. | ||
*/ | ||
var typeMap = { | ||
hue: 'deg' | ||
, saturation: '%' | ||
, lightness: '%' | ||
}; | ||
/** | ||
* Convert the given `color` to an `HSLA` node, | ||
@@ -111,67 +135,6 @@ * or h,s,l,a component values. | ||
/** | ||
* Return the hue of the given `color`. | ||
* Return component `name` for the given `color`. | ||
* | ||
* Examples: | ||
* | ||
* hue(hsl(50deg, 100%, 80%)) | ||
* // => 50deg | ||
* | ||
* @param {HSLA|Color} color | ||
* @return {Unit} | ||
* @api public | ||
*/ | ||
exports.hue = function(color){ | ||
utils.assertColor(color, 'hue'); | ||
return new nodes.Unit(Math.round(color.hsl.h), 'deg'); | ||
}; | ||
/** | ||
* Return the saturation of the given `color`. | ||
* | ||
* Examples: | ||
* | ||
* saturation(hsl(50deg, 100%, 80%)) | ||
* // => 100% | ||
* | ||
* @param {HSLA|Color} color | ||
* @return {Unit} | ||
* @api public | ||
*/ | ||
exports.saturation = function(color){ | ||
utils.assertColor(color, 'saturation'); | ||
return new nodes.Unit(Math.round(color.hsl.s), '%'); | ||
}; | ||
/** | ||
* Return the lightness of the given `color`. | ||
* | ||
* Examples: | ||
* | ||
* lightness(hsl(50def, 100%, 80%)) | ||
* // => 80% | ||
* | ||
* @param {HSLA|Color} color | ||
* @return {Unit} | ||
* @api public | ||
*/ | ||
exports.lightness = function(color){ | ||
utils.assertColor(color, 'lightness'); | ||
return new nodes.Unit(Math.round(color.hsl.l), '%'); | ||
}; | ||
/** | ||
* Return the alpha component of the given `color`. | ||
* | ||
* Examples: | ||
* | ||
* alpha(#fff) | ||
* // => 1 | ||
* | ||
* alpha(rgba(0,0,0,0.3)) | ||
* // => 0.3 | ||
* | ||
* @param {Color|HSLA} color | ||
* @param {String} na,e | ||
* @return {Unit} | ||
@@ -181,5 +144,10 @@ * @api public | ||
exports.alpha = function(color){ | ||
utils.assertColor(color, 'alpha'); | ||
return new nodes.Unit(color.rgba.a); | ||
exports.component = function(color, name) { | ||
utils.assertColor(color, 'color'); | ||
utils.assertString(name, 'name'); | ||
var name = name.string | ||
, type = typeMap[name] | ||
, name = componentMap[name]; | ||
if (!name) throw new Error('invalid color component "' + name + '"'); | ||
return new nodes.Unit(color[name], type); | ||
}; | ||
@@ -201,4 +169,3 @@ | ||
exports.red = function(color){ | ||
utils.assertColor(color, 'red'); | ||
return new nodes.Unit(color.rgba.r); | ||
return exports.component(color, new nodes.String('red')); | ||
}; | ||
@@ -220,4 +187,3 @@ | ||
exports.green = function(color){ | ||
utils.assertColor(color, 'green'); | ||
return new nodes.Unit(color.rgba.g); | ||
return exports.component(color, new nodes.String('green')); | ||
}; | ||
@@ -239,4 +205,3 @@ | ||
exports.blue = function(color){ | ||
utils.assertColor(color, 'blue'); | ||
return new nodes.Unit(color.rgba.b); | ||
return exports.component(color, new nodes.String('blue')); | ||
}; | ||
@@ -353,230 +318,2 @@ | ||
/** | ||
* Absolute value of `n`. | ||
* | ||
* @param {Unit} n | ||
* @return {Unit} | ||
* @api public | ||
*/ | ||
exports.abs = function(n){ | ||
utils.assertType(n, nodes.Unit, 'unit'); | ||
return new nodes.Unit(Math.abs(n.val), n.type); | ||
}; | ||
/** | ||
* Nearest integer above `n`. | ||
* | ||
* @param {Unit} n | ||
* @return {Unit} | ||
* @api public | ||
*/ | ||
exports.ceil = function(n){ | ||
utils.assertType(n, nodes.Unit, 'unit'); | ||
return new nodes.Unit(Math.ceil(n.val), n.type); | ||
}; | ||
/** | ||
* Nearest integer below `n`. | ||
* | ||
* @param {Unit} n | ||
* @return {Unit} | ||
* @api public | ||
*/ | ||
exports.floor = function(n){ | ||
utils.assertType(n, nodes.Unit, 'unit'); | ||
return new nodes.Unit(Math.floor(n.val), n.type); | ||
}; | ||
/** | ||
* Round `n`. | ||
* | ||
* @param {Unit} n | ||
* @return {Unit} | ||
* @api public | ||
*/ | ||
exports.round = function(n){ | ||
utils.assertType(n, nodes.Unit, 'unit'); | ||
return new nodes.Unit(Math.round(n.val), n.type); | ||
}; | ||
/** | ||
* Min of `a` and `b`. | ||
* | ||
* @param {Unit} a | ||
* @param {Unit} b | ||
* @return {Unit} | ||
* @api public | ||
*/ | ||
exports.min = function(a, b){ | ||
utils.assertType(a, nodes.Unit, 'a'); | ||
utils.assertType(b, nodes.Unit, 'b'); | ||
return a.val < b.val ? a : b; | ||
}; | ||
/** | ||
* Max of `a` and `b`. | ||
* | ||
* @param {Unit} a | ||
* @param {Unit} b | ||
* @return {Unit} | ||
* @api public | ||
*/ | ||
exports.max = function(a, b){ | ||
utils.assertType(a, nodes.Unit, 'a'); | ||
utils.assertType(b, nodes.Unit, 'b'); | ||
return a.val > b.val ? a : b; | ||
}; | ||
/** | ||
* Check if `n` is even. | ||
* | ||
* @param {Unit} n | ||
* @return {Boolean} | ||
* @api public | ||
*/ | ||
exports.even = function(n){ | ||
utils.assertType(n, nodes.Unit, 'unit'); | ||
return nodes.Boolean(0 == n % 2); | ||
}; | ||
/** | ||
* Check if `n` is odd. | ||
* | ||
* @param {Unit} n | ||
* @return {Boolean} | ||
* @api public | ||
*/ | ||
exports.odd = function(n){ | ||
utils.assertType(n, nodes.Unit, 'unit'); | ||
return nodes.Boolean(1 == n % 2); | ||
}; | ||
/** | ||
* Saturate `color` by `amount`. | ||
* | ||
* @param {Color|HSLA} color | ||
* @param {Unit} amount | ||
* @return {HSLA} | ||
* @api public | ||
*/ | ||
exports.saturate = function(color, amount){ | ||
utils.assertColor(color, 'color'); | ||
utils.assertType(amount, nodes.Unit, 'amount'); | ||
var hsl = color.hsl; | ||
return new nodes.HSLA( | ||
hsl.h | ||
, hsl.s + amount.val | ||
, hsl.l | ||
, hsl.a); | ||
}; | ||
/** | ||
* Desaturate `color` by `amount`. | ||
* | ||
* @param {Color|HSLA} color | ||
* @param {Unit} amount | ||
* @return {HSLA} | ||
* @api public | ||
*/ | ||
exports.desaturate = function(color, amount){ | ||
utils.assertColor(color, 'color'); | ||
utils.assertType(amount, nodes.Unit, 'amount'); | ||
var hsl = color.hsl; | ||
return new nodes.HSLA( | ||
hsl.h | ||
, hsl.s - amount.val | ||
, hsl.l | ||
, hsl.a); | ||
}; | ||
/** | ||
* Lighten `color` by `amount` of the current value. | ||
* | ||
* @param {Color|HSLA} color | ||
* @param {Unit} amount | ||
* @return {HSLA} | ||
* @api public | ||
*/ | ||
exports['lighten-by'] = function(color, amount){ | ||
utils.assertColor(color, 'color'); | ||
utils.assertType(amount, nodes.Unit, 'amount'); | ||
var hsl = color.hsl; | ||
return new nodes.HSLA( | ||
hsl.h | ||
, hsl.s | ||
, hsl.l + (hsl.l || 100) * amount.val / 100 | ||
, hsl.a); | ||
}; | ||
/** | ||
* Lighten `color` by `amount`. | ||
* | ||
* @param {Color|HSLA} color | ||
* @param {Unit} amount | ||
* @return {HSLA} | ||
* @api public | ||
*/ | ||
exports.lighten = function(color, amount){ | ||
utils.assertColor(color, 'color'); | ||
utils.assertType(amount, nodes.Unit, 'amount'); | ||
var hsl = color.hsl; | ||
return new nodes.HSLA( | ||
hsl.h | ||
, hsl.s | ||
, hsl.l + amount.val | ||
, hsl.a); | ||
}; | ||
/** | ||
* Darken `color` by `amount`. | ||
* | ||
* @param {Color|HSLA} color | ||
* @param {Unit} amount | ||
* @return {HSLA} | ||
* @api public | ||
*/ | ||
exports.darken = function(color, amount){ | ||
utils.assertColor(color, 'color'); | ||
utils.assertType(amount, nodes.Unit, 'amount'); | ||
var hsl = color.hsl; | ||
return new nodes.HSLA( | ||
hsl.h | ||
, hsl.s | ||
, hsl.l - amount.val | ||
, hsl.a); | ||
}; | ||
/** | ||
* Darken `color` by `amount` of the current value. | ||
* | ||
* @param {Color|HSLA} color | ||
* @param {Unit} amount | ||
* @return {HSLA} | ||
* @api public | ||
*/ | ||
exports['darken-by'] = function(color, amount){ | ||
utils.assertColor(color, 'color'); | ||
utils.assertType(amount, nodes.Unit, 'amount'); | ||
var hsl = color.hsl; | ||
return new nodes.HSLA( | ||
hsl.h | ||
, hsl.s | ||
, hsl.l - hsl.l * amount.val / 100 | ||
, hsl.a); | ||
}; | ||
/** | ||
* Assign `type` to the given `unit` or return `unit`'s type. | ||
@@ -791,2 +528,33 @@ * | ||
return expr; | ||
}; | ||
/** | ||
* Apply Math `fn` to `n` | ||
* | ||
* @param {Unit} n | ||
* @param {String} fn | ||
* @return {Unit} | ||
* @api private | ||
*/ | ||
exports['-math'] = function(n, fn){ | ||
return new nodes.Unit(Math[fn.string](n.val), n.type); | ||
}; | ||
/** | ||
* Adjust HSL `color` `prop` by `amount`. | ||
* | ||
* @param {Color|HSLA} color | ||
* @param {String} prop | ||
* @param {Unit} amount | ||
* @return {HSLA} | ||
* @api private | ||
*/ | ||
exports['-adjust'] = function(color, prop, amount){ | ||
var hsl = color.hsl; | ||
prop = { hue: 'h', saturation: 's', lightness: 'l' }[prop.string]; | ||
if (!prop) throw new Error('invalid adjustment property'); | ||
hsl[prop] = hsl[prop] + amount.val; | ||
return hsl.clone(); | ||
}; |
@@ -23,2 +23,3 @@ | ||
, 'is': '==' | ||
, 'isnt': '!=' | ||
, 'is not': '!=' | ||
@@ -158,2 +159,3 @@ }; | ||
|| this.keyword | ||
|| this.urlchars | ||
|| this.atrule | ||
@@ -217,2 +219,15 @@ || this.media | ||
/** | ||
* url char | ||
*/ | ||
get urlchars() { | ||
var captures; | ||
if (!this.isURL) return; | ||
if (captures = /^[\/:@.;?&=*!,<>#%0-9]+/.exec(this.str)) { | ||
this.skip(captures); | ||
return new Token('literal', new nodes.Literal(captures[0])); | ||
} | ||
}, | ||
/** | ||
* ';' ' '* | ||
@@ -355,2 +370,3 @@ */ | ||
* | 'is not' | ||
* | 'isnt' | ||
* | 'is a' | ||
@@ -362,3 +378,3 @@ * | 'is defined' | ||
var captures; | ||
if (captures = /^(not|and|or|is a|is defined|is not|is)\b( *)/.exec(this.str)) { | ||
if (captures = /^(not|and|or|is a|is defined|isnt|is not|is)\b( *)/.exec(this.str)) { | ||
var op = captures[1]; | ||
@@ -603,10 +619,2 @@ this.skip(captures); | ||
var captures; | ||
// url() special case | ||
if (this.isURL && (captures = /^([^'")]+) */.exec(this.str))) { | ||
this.skip(captures); | ||
return new Token('string', new nodes.String(captures[1])); | ||
} | ||
// Regular string | ||
if (captures = /^("[^"]*"|'[^']*') */.exec(this.str)) { | ||
@@ -613,0 +621,0 @@ var str = captures[1]; |
@@ -1,2 +0,1 @@ | ||
/*! | ||
@@ -32,8 +31,9 @@ * Stylus - middleware | ||
* | ||
* `force` Always re-compile | ||
* `src` Source directory used to find .styl files | ||
* `dest` Destination directory used to output .css files | ||
* when undefined defaults to `src`. | ||
* `compile` Custom compile function, accepting the arguments | ||
* `(str, path, callback)`. | ||
* `force` Always re-compile | ||
* `src` Source directory used to find .styl files | ||
* `dest` Destination directory used to output .css files | ||
* when undefined defaults to `src`. | ||
* `compile` Custom compile function, accepting the arguments | ||
* `(str, path, callback)`. | ||
* `compress` Whether the output .css files should be compressed | ||
* | ||
@@ -99,2 +99,3 @@ * Examples: | ||
.set('filename', path) | ||
.set('compress', options.compress) | ||
.render(fn); | ||
@@ -101,0 +102,0 @@ }; |
@@ -15,12 +15,11 @@ | ||
/** | ||
* Initialize a new `Import` with the given `path`. | ||
* Initialize a new `Import` with the given `expr`. | ||
* | ||
* @param {String} path | ||
* @param {Expression} expr | ||
* @api public | ||
*/ | ||
var Import = module.exports = function Import(path){ | ||
var Import = module.exports = function Import(expr){ | ||
Node.call(this); | ||
this.path = path; | ||
this.literal = !! ~path.indexOf('.css'); | ||
this.path = expr; | ||
}; | ||
@@ -27,0 +26,0 @@ |
@@ -577,3 +577,3 @@ | ||
/** | ||
* import string | ||
* import expression | ||
*/ | ||
@@ -584,3 +584,3 @@ | ||
this.allowPostfix = true; | ||
return new nodes.Import(this.expect('string').val.val); | ||
return new nodes.Import(this.expression); | ||
}, | ||
@@ -962,4 +962,17 @@ | ||
}, | ||
/** | ||
* url '(' (expression | urlchars)+ ')' | ||
*/ | ||
get url() { | ||
this.expect('function'); | ||
this.state.push('function arguments'); | ||
var args = this.args; | ||
this.expect(')'); | ||
this.state.pop(); | ||
return new nodes.Call('url', args); | ||
}, | ||
/** | ||
* ident '(' expression ')' | ||
@@ -969,2 +982,3 @@ */ | ||
get functionCall() { | ||
if ('url' == this.peek.val.name) return this.url; | ||
var name = this.expect('function').val.name; | ||
@@ -971,0 +985,0 @@ this.state.push('function arguments'); |
@@ -29,3 +29,3 @@ | ||
options.functions = {}; | ||
options.imports = []; | ||
options.imports = [__dirname + '/functions']; | ||
options.filename = options.filename || 'stylus'; | ||
@@ -32,0 +32,0 @@ this.str = str; |
@@ -26,3 +26,3 @@ | ||
exports.version = '0.7.1'; | ||
exports.version = '0.7.2'; | ||
@@ -29,0 +29,0 @@ /** |
@@ -311,3 +311,5 @@ | ||
Compiler.prototype.visitString = function(string){ | ||
return string.toString(); | ||
return this.isURL | ||
? string.val | ||
: string.toString(); | ||
}; | ||
@@ -328,5 +330,8 @@ | ||
Compiler.prototype.visitCall = function(call){ | ||
this.isURL = 'url' == call.name; | ||
var args = call.args.nodes.map(function(arg){ | ||
return this.visit(arg); | ||
}, this).join(this.compress ? ',' : ', '); | ||
if (this.isURL) args = '"' + args + '"'; | ||
delete this.isURL; | ||
return call.name + '(' + args + ')'; | ||
@@ -340,3 +345,3 @@ }; | ||
Compiler.prototype.visitImport = function(import){ | ||
return '@import "' + import.path + '";'; | ||
return '@import ' + this.visit(import.path) + ';'; | ||
}; | ||
@@ -353,3 +358,3 @@ | ||
? (this.compress ? ',' : ', ') | ||
: ' '); | ||
: (this.isURL ? '' : ' ')); | ||
}; | ||
@@ -356,0 +361,0 @@ |
@@ -91,3 +91,5 @@ | ||
this.imports.forEach(function(file){ | ||
this.visit(new nodes.Import(file)); | ||
var expr = new nodes.Expression; | ||
expr.push(new nodes.String(file)); | ||
this.visit(new nodes.Import(expr)); | ||
}, this); | ||
@@ -178,3 +180,3 @@ }; | ||
var local = this.stack.currentFrame.scope.lookup(fn.name); | ||
if (local) this.warn('local ' + local.nodeName + ' "' + fn.name + '" previously defined in this scope on line ' + local.lineno); | ||
if (local) this.warn('local ' + local.nodeName + ' "' + fn.name + '" previously defined in this scope'); | ||
@@ -522,5 +524,9 @@ // user-defined | ||
, stylus = require('../stylus') | ||
, path = import.path | ||
, path = this.visit(import.path).first | ||
, relative = this.importPath; | ||
// Enusre string | ||
if (!path.string) throw new Error('@import string expected'); | ||
var name = path = path.string; | ||
// Literal | ||
@@ -533,2 +539,3 @@ if (/\.css$/.test(path)) return import; | ||
found = utils.lookup(path, this.paths, this.filename); | ||
found = found || utils.lookup(name + '/index.styl', this.paths, this.filename); | ||
if (relative) this.paths.pop(); | ||
@@ -535,0 +542,0 @@ |
{ "name": "stylus" | ||
, "description": "Robust, expressive language which compiles to CSS" | ||
, "version": "0.7.1" | ||
, "version": "0.7.2" | ||
, "author": "TJ Holowaychuk <tj@vision-media.ca>" | ||
@@ -5,0 +5,0 @@ , "keywords": ["css", "parser", "style", "stylesheets", "jade", "language"] |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
63
184797
6526