├── .gitmodules ├── examples ├── public │ └── .gitignore ├── images │ ├── jesus.gif │ ├── gopher.jpg │ ├── sprite.gif │ └── gradient.svg ├── literal.styl ├── import.styl ├── basic.styl ├── gradients.styl ├── mixins │ └── box.styl ├── nesting.styl ├── comments.js ├── basic.js ├── comments.styl ├── literal.js ├── nesting.js ├── builtins.js ├── functions.js ├── variables.js ├── arithmetic.js ├── conversions.js ├── import.js ├── compress.js ├── gradients.js ├── implicit-functions.js ├── images.styl ├── implicit-functions.styl ├── js-functions.styl ├── variables.styl ├── conversions.styl ├── middleware.js ├── arithmetic.styl ├── functions.styl ├── images.js ├── builtins.styl └── js-functions.js ├── test ├── cases │ ├── rule.charset.css │ ├── import.basic.styl │ ├── import.complex │ │ ├── c.styl │ │ ├── a.styl │ │ └── nested │ │ │ └── b.styl │ ├── import.index │ │ └── vendor │ │ │ ├── b.styl │ │ │ ├── a.styl │ │ │ ├── c.styl │ │ │ └── index.styl │ ├── import.ordering │ │ ├── two.styl │ │ ├── five.styl │ │ └── four.styl │ ├── rule.charset.styl │ ├── variable.css │ ├── import.basic │ │ ├── c.styl │ │ ├── a.styl │ │ └── b.styl │ ├── import.complex.styl │ ├── mixins.root.css │ ├── bifs.lookup.css │ ├── compress.comments.css │ ├── import.index.styl │ ├── jquery.css │ ├── regression.127.styl │ ├── functions.nested-calls.css │ ├── regression.127.css │ ├── self-assignment.css │ ├── variable.styl │ ├── functions.call.css │ ├── functions.variable.ident.css │ ├── mixins.conditional.css │ ├── mixins.return.css │ ├── rulset.styl │ ├── bifs.match.css │ ├── import.literal.css │ ├── mixins.root.styl │ ├── regression.244.css │ ├── rulset.css │ ├── import.literal.styl │ ├── list.styl │ ├── properties.styl │ ├── regression.244.styl │ ├── regression.267.styl │ ├── regression.368.css │ ├── bifs.dark.css │ ├── bifs.last.css │ ├── bifs.light.css │ ├── function.arguments.css │ ├── functions.arg-calls.css │ ├── list.css │ ├── properties.css │ ├── regression.156.css │ ├── regression.267.css │ ├── important.styl │ ├── jquery.styl │ ├── regression.243.css │ ├── rulset.newline.styl │ ├── compress.comments.styl │ ├── conditional-assignment.css │ ├── escape.css │ ├── escape.styl │ ├── regression.243.styl │ ├── rulset.newline.css │ ├── bifs.unit.css │ ├── important.css │ ├── regression.139.css │ ├── regression.220.css │ ├── regression.368.styl │ ├── if.else.css │ ├── regression.131.styl │ ├── regression.137.styl │ ├── regression.233.css │ ├── regression.247.styl │ ├── scope.css │ ├── bifs.unquote.css │ ├── coercion.css │ ├── fontface.css │ ├── functions.call.styl │ ├── import.index.css │ ├── keyframes.styl │ ├── regression.131.css │ ├── regression.233.styl │ ├── regression.247.css │ ├── coercion.styl │ ├── fontface.styl │ ├── import.complex.css │ ├── introspection.css │ ├── literal.color.styl │ ├── mixins.return.styl │ ├── regression.220.styl │ ├── self-assignment.styl │ ├── bifs.dark.styl │ ├── bifs.light.styl │ ├── bifs.unit.styl │ ├── css.if.css │ ├── import.basic.css │ ├── regression.137.css │ ├── regression.154.css │ ├── bifs.darken.css │ ├── bifs.rgba.styl │ ├── import.mixins.styl │ ├── mixins.nested.css │ ├── keyframes.css │ ├── regression.153.css │ ├── regression.270.css │ ├── scope.nested.css │ ├── bifs.last.styl │ ├── bifs.rgba.css │ ├── functions.multi-line.css │ ├── if.mixin.css │ ├── import.mixins.css │ ├── mixin.order.css │ ├── regression.153.styl │ ├── regression.156.styl │ ├── function.literals.css │ ├── properties.colons.css │ ├── bifs.lookup.styl │ ├── css.functions.single-line.css │ ├── literal.color.css │ ├── mixin.order.nested.css │ ├── regression.260.css │ ├── regression.260.styl │ ├── regression.270.styl │ ├── bifs.opposite-position.css │ ├── compress.units.css │ ├── keyframes.fabrication.defaults.styl │ ├── bifs.length.css │ ├── functions.nested-calls.styl │ ├── mixins.conditional.styl │ ├── operators.complex.css │ ├── regression.248.compressed.css │ ├── bifs.image-size.css │ ├── functions.nested.css │ ├── functions.arg-calls.styl │ ├── properties.colons.styl │ ├── regression.235.css │ ├── selectors.nested.comma.styl │ ├── conditional-assignment.styl │ ├── regression.216.styl │ ├── functions.variable.css │ ├── functions.variable.ident.styl │ ├── mixins.order.2.css │ ├── bifs.match.styl │ ├── bifs.unquote.styl │ ├── keyframes.fabrication.styl │ ├── scope.nested.styl │ ├── import.ordering.styl │ ├── literal.css │ ├── mixin.order.conditional.css │ ├── selectors.nested.comma.css │ ├── functions.return.each.css │ ├── properties.one-line.css │ ├── properties.one-line.styl │ ├── regression.235.styl │ ├── regression.272.css │ ├── bifs.components.css │ ├── import.ordering.css │ ├── mixins │ │ └── box.styl │ ├── operators.mixins.css │ ├── bifs.darken.styl │ ├── bifs.join.css │ ├── functions.css │ ├── operators.assignment.function.css │ ├── operators.assignment.mixin.css │ ├── regression.130.styl │ ├── regression.216.css │ ├── function.literals.styl │ ├── page.styl │ ├── regression.229.styl │ ├── scope.styl │ ├── regression.248.compressed.styl │ ├── operators.subscript.range.css │ ├── scope.complex.css │ ├── functions.property.styl │ ├── mixins.nested.styl │ ├── page.css │ ├── media.styl │ ├── bifs.lighten.css │ ├── function.arguments.styl │ ├── introspection.styl │ ├── css.functions.single-line.styl │ ├── functions.property.css │ ├── functions.return.css │ ├── regression.229.css │ ├── regression.252.css │ ├── bifs.s.css │ ├── css.media.css │ ├── operators.assignment.root.css │ ├── regression.154.styl │ ├── regression.274.css │ ├── bifs.join.styl │ ├── mixin.order.styl │ ├── regression.130.css │ ├── compress.units.styl │ ├── css.media.styl │ ├── mixins.complex.fix-to.css │ ├── mixins.order.2.styl │ ├── operator.range.css │ ├── comments.css │ ├── functions.defaults.css │ ├── keyframes.fabrication.css │ ├── media.css │ ├── mixin.order.nested.styl │ ├── regression.360.styl │ ├── variables.css │ ├── bifs.type.css │ ├── functions.multiple-calls.css │ ├── if.selectors.css │ ├── regression.107.lookup-failure.css │ ├── regression.212.css │ ├── operators.subscript.range.styl │ ├── scope.complex.styl │ ├── bifs.components.styl │ ├── bifs.opposite-position.styl │ ├── functions.multi-line.styl │ ├── mixin.order.conditional.styl │ ├── css.if.styl │ ├── mixin.conditional.css │ ├── regression.107.lookup-failure.styl │ ├── regression.252.styl │ ├── for.function.css │ ├── if.else.styl │ ├── variables.styl │ ├── literal.styl │ ├── arithmetic.css │ ├── regression.212.styl │ ├── arithmetic.unary.styl │ ├── bifs.s.styl │ ├── bifs.type.styl │ ├── bifs.image-size.styl │ ├── mixins.nested.selectors.css │ ├── arithmetic.unary.css │ ├── bifs.length.styl │ ├── bifs.lighten.styl │ ├── css.mixins.root.wonky.styl │ ├── regression.272.styl │ ├── bifs.push.css │ ├── if.selectors.styl │ ├── operators.subscript.assign.css │ ├── regression.360.css │ ├── comments.styl │ ├── keyframes.fabrication.defaults.css │ ├── regression.274.styl │ ├── vargs.call.css │ ├── bifs.url.css │ ├── functions.multiple-calls.styl │ ├── functions.variable.styl │ ├── operators.assignment.function.styl │ ├── bifs.url.styl │ ├── css.mixins.root.styl │ ├── hack.star.css │ ├── if.mixin.styl │ ├── operators.equality.css │ ├── operator.range.styl │ ├── selectors.pseudo.styl │ ├── operators.assignment.root.styl │ ├── functions.defaults.styl │ ├── mixins.nested.selectors.styl │ ├── operators.assignment.mixin.styl │ ├── arithmetic.styl │ ├── operators.mixins.styl │ ├── regression.146.css │ ├── selectors.nested.styl │ ├── regression.146.styl │ ├── functions.return.each.styl │ ├── selectors.pseudo.elements.styl │ ├── vargs.css │ ├── hack.star.styl │ ├── css.whitespace.styl │ ├── regression.139.styl │ ├── selectors.complex.styl │ ├── css.whitespace.css │ ├── for.complex.styl │ ├── reset.styl │ ├── mixins.complex.fix-to.styl │ ├── selectors.complex.css │ ├── operators.in.css │ ├── regression.142.css │ ├── css.mixins.root.css │ ├── css.mixins.root.wonky.css │ ├── mixin.conditional.styl │ ├── functions.nested.styl │ ├── selectors.nested.css │ ├── arithmetic.color.css │ ├── if.css │ ├── operators.complex.styl │ ├── parent.css │ ├── parent.styl │ ├── operators.equality.styl │ ├── css.selectors.css │ ├── selectors.styl │ ├── property-access.css │ ├── vargs.call.styl │ ├── mixins.complex.css │ ├── functions.styl │ ├── for.complex.css │ ├── for.styl │ ├── regression.142.styl │ ├── bifs.push.styl │ ├── css.keyframes.styl │ ├── operators.css │ ├── arithmetic.color.styl │ ├── mixins.reset.styl │ ├── operators.precedence.css │ ├── operators.subscript.assign.styl │ ├── for.css │ ├── property-access.styl │ ├── selectors.css │ ├── bifs.add-property.css │ ├── vargs.styl │ ├── css.keyframes.css │ ├── mixins.complex.styl │ ├── css.selectors.styl │ ├── selector.interpolation.styl │ ├── selectors.pseudo.css │ ├── reset.css │ ├── interpolation.properties.css │ ├── if.postfix.css │ ├── selector.interpolation.css │ ├── operators.subscript.css │ ├── selectors.pseudo.elements.css │ ├── operators.in.styl │ ├── mixins.reset.css │ ├── css.mixins.css │ ├── css.mixins.braces.css │ ├── for.function.styl │ ├── interpolation.properties.styl │ ├── kwargs.css │ ├── css.mixins.styl │ ├── bifs.add-property.styl │ ├── css.mixins.braces.styl │ ├── functions.return.styl │ ├── if.styl │ ├── css.selector.interpolation.css │ ├── operators.subscript.styl │ ├── css.selector.interpolation.styl │ ├── kwargs.styl │ └── operators.precedence.styl └── images │ ├── gif │ ├── tux.png │ └── squirrel.jpeg ├── index.js ├── .gitignore ├── .npmignore ├── docs ├── textmate.md ├── literal.md ├── media.md ├── escape.md ├── font-face.md ├── comments.md ├── pseudo-elements.md ├── kwargs.md ├── introspection.md ├── gedit.md ├── error-reporting.md ├── interpolation.md ├── compare.md └── functions.url.md ├── editors └── Stylus.tmbundle │ ├── info.plist │ ├── Commands │ └── Compile and Display CSS.tmCommand │ └── Preferences │ └── Comments.tmPreferences ├── Makefile ├── package.json ├── lib ├── nodes │ ├── import.js │ ├── jsliteral.js │ ├── comment.js │ ├── media.js │ ├── charset.js │ ├── page.js │ ├── root.js │ ├── return.js │ ├── unaryop.js │ ├── fontface.js │ ├── call.js │ ├── binop.js │ ├── ternary.js │ ├── each.js │ ├── selector.js │ ├── if.js │ ├── null.js │ ├── arguments.js │ └── params.js ├── visitor │ └── index.js ├── stack │ ├── scope.js │ └── frame.js ├── token.js └── errors.js ├── bm.js └── LICENSE /.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/public/.gitignore: -------------------------------------------------------------------------------- 1 | *.css -------------------------------------------------------------------------------- /test/cases/rule.charset.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8" -------------------------------------------------------------------------------- /test/cases/import.basic.styl: -------------------------------------------------------------------------------- 1 | 2 | @import "a" 3 | -------------------------------------------------------------------------------- /test/cases/import.complex/c.styl: -------------------------------------------------------------------------------- 1 | three 2 | foo bar -------------------------------------------------------------------------------- /test/cases/import.index/vendor/b.styl: -------------------------------------------------------------------------------- 1 | body 2 | two 2 -------------------------------------------------------------------------------- /test/cases/import.ordering/two.styl: -------------------------------------------------------------------------------- 1 | two 2 | foo bar -------------------------------------------------------------------------------- /test/cases/rule.charset.styl: -------------------------------------------------------------------------------- 1 | 2 | @charset "utf-8" -------------------------------------------------------------------------------- /test/cases/variable.css: -------------------------------------------------------------------------------- 1 | body { 2 | font: 12px; 3 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = require('./lib/stylus'); -------------------------------------------------------------------------------- /test/cases/import.basic/c.styl: -------------------------------------------------------------------------------- 1 | 2 | .c 3 | color blue -------------------------------------------------------------------------------- /test/cases/import.complex.styl: -------------------------------------------------------------------------------- 1 | @import "./import.complex/a" -------------------------------------------------------------------------------- /test/cases/import.index/vendor/a.styl: -------------------------------------------------------------------------------- 1 | body 2 | one 1 -------------------------------------------------------------------------------- /test/cases/import.index/vendor/c.styl: -------------------------------------------------------------------------------- 1 | body 2 | three 3 -------------------------------------------------------------------------------- /test/cases/import.ordering/five.styl: -------------------------------------------------------------------------------- 1 | five 2 | foo bar -------------------------------------------------------------------------------- /test/cases/mixins.root.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 5px; 3 | } -------------------------------------------------------------------------------- /test/cases/bifs.lookup.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #006269; 3 | } -------------------------------------------------------------------------------- /test/cases/compress.comments.css: -------------------------------------------------------------------------------- 1 | /* baz */ 2 | body{foo:"bar"} -------------------------------------------------------------------------------- /test/cases/import.index.styl: -------------------------------------------------------------------------------- 1 | 2 | @import 'import.index/vendor' -------------------------------------------------------------------------------- /test/cases/jquery.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 10px 10px; 3 | } -------------------------------------------------------------------------------- /test/cases/regression.127.styl: -------------------------------------------------------------------------------- 1 | body 2 | background #c3210d -------------------------------------------------------------------------------- /test/cases/functions.nested-calls.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 13; 3 | } -------------------------------------------------------------------------------- /test/cases/regression.127.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #c3210d; 3 | } -------------------------------------------------------------------------------- /test/cases/self-assignment.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #fff; 3 | } -------------------------------------------------------------------------------- /test/cases/variable.styl: -------------------------------------------------------------------------------- 1 | size = 12px 2 | 3 | body 4 | font size -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | css 2 | lib-cov 3 | testing 4 | .DS_Store 5 | node_modules 6 | -------------------------------------------------------------------------------- /test/cases/functions.call.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 15; 3 | foo: 7; 4 | } -------------------------------------------------------------------------------- /test/cases/functions.variable.ident.css: -------------------------------------------------------------------------------- 1 | body { 2 | font: 28px; 3 | } -------------------------------------------------------------------------------- /test/cases/mixins.conditional.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 5px 10px; 3 | } -------------------------------------------------------------------------------- /test/cases/mixins.return.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: bar; 3 | bar: baz; 4 | } -------------------------------------------------------------------------------- /test/cases/rulset.styl: -------------------------------------------------------------------------------- 1 | 2 | textarea, input 3 | border 1px solid #eee -------------------------------------------------------------------------------- /test/cases/bifs.match.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 5px; 3 | padding: 5px; 4 | } -------------------------------------------------------------------------------- /test/cases/import.basic/a.styl: -------------------------------------------------------------------------------- 1 | 2 | .a 3 | color red 4 | 5 | @import "b" -------------------------------------------------------------------------------- /test/cases/import.basic/b.styl: -------------------------------------------------------------------------------- 1 | 2 | .b 3 | color green 4 | 5 | @import "c" -------------------------------------------------------------------------------- /test/cases/import.literal.css: -------------------------------------------------------------------------------- 1 | @import "foo/bar.css"; 2 | @import "bar/baz.css"; -------------------------------------------------------------------------------- /test/cases/mixins.root.styl: -------------------------------------------------------------------------------- 1 | foo() 2 | body 3 | padding 5px 4 | 5 | foo() -------------------------------------------------------------------------------- /test/cases/regression.244.css: -------------------------------------------------------------------------------- 1 | a[href^="error"] { 2 | background: #f00; 3 | } -------------------------------------------------------------------------------- /test/cases/rulset.css: -------------------------------------------------------------------------------- 1 | textarea, 2 | input { 3 | border: 1px solid #eee; 4 | } -------------------------------------------------------------------------------- /test/images/gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/stylus/master/test/images/gif -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | support 3 | testing 4 | docs 5 | examples 6 | node_modules 7 | -------------------------------------------------------------------------------- /test/cases/import.complex/a.styl: -------------------------------------------------------------------------------- 1 | one 2 | foo bar 3 | 4 | @import "./nested/b" -------------------------------------------------------------------------------- /test/cases/import.complex/nested/b.styl: -------------------------------------------------------------------------------- 1 | two 2 | foo bar 3 | 4 | @import "../c" -------------------------------------------------------------------------------- /test/cases/import.literal.styl: -------------------------------------------------------------------------------- 1 | 2 | @import "foo/bar.css" 3 | @import 'bar/baz.css' -------------------------------------------------------------------------------- /test/cases/list.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | font 12px "Lucida Grande", Arial, sans-serif -------------------------------------------------------------------------------- /test/cases/properties.styl: -------------------------------------------------------------------------------- 1 | 2 | #wrapper 3 | padding 5px 4 | white-space nowrap -------------------------------------------------------------------------------- /test/cases/regression.244.styl: -------------------------------------------------------------------------------- 1 | 2 | a[href^="error"] 3 | background: red 4 | -------------------------------------------------------------------------------- /test/cases/regression.267.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | foo: url(images/white/something.png) -------------------------------------------------------------------------------- /test/cases/regression.368.css: -------------------------------------------------------------------------------- 1 | .small { 2 | font: 7px; 3 | line-height: 1; 4 | } -------------------------------------------------------------------------------- /test/cases/bifs.dark.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: true; 3 | foo: true; 4 | foo: true; 5 | } -------------------------------------------------------------------------------- /test/cases/bifs.last.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: true; 3 | foo: true; 4 | foo: true; 5 | } -------------------------------------------------------------------------------- /test/cases/bifs.light.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: true; 3 | foo: true; 4 | foo: true; 5 | } -------------------------------------------------------------------------------- /test/cases/function.arguments.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 15; 3 | padding: 1 2; 4 | } -------------------------------------------------------------------------------- /test/cases/functions.arg-calls.css: -------------------------------------------------------------------------------- 1 | form input { 2 | padding: 10px 5px 10px 5px; 3 | } -------------------------------------------------------------------------------- /test/cases/list.css: -------------------------------------------------------------------------------- 1 | body { 2 | font: 12px "Lucida Grande", Arial, sans-serif; 3 | } -------------------------------------------------------------------------------- /test/cases/properties.css: -------------------------------------------------------------------------------- 1 | #wrapper { 2 | padding: 5px; 3 | white-space: nowrap; 4 | } -------------------------------------------------------------------------------- /test/cases/regression.156.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-right: 0; 3 | float: right; 4 | } -------------------------------------------------------------------------------- /test/cases/regression.267.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: url("images/white/something.png"); 3 | } -------------------------------------------------------------------------------- /test/images/tux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/stylus/master/test/images/tux.png -------------------------------------------------------------------------------- /test/cases/import.index/vendor/index.styl: -------------------------------------------------------------------------------- 1 | 2 | @import 'a' 3 | @import 'b' 4 | @import 'c' -------------------------------------------------------------------------------- /test/cases/important.styl: -------------------------------------------------------------------------------- 1 | 2 | a 3 | color red !important 4 | 5 | a.button 6 | color blue -------------------------------------------------------------------------------- /test/cases/jquery.styl: -------------------------------------------------------------------------------- 1 | pad( x , y = x ) 2 | padding x y 3 | 4 | body 5 | pad( 10px ) -------------------------------------------------------------------------------- /test/cases/regression.243.css: -------------------------------------------------------------------------------- 1 | div.flash.success + div.flash.error { 2 | color: #f00; 3 | } -------------------------------------------------------------------------------- /test/cases/rulset.newline.styl: -------------------------------------------------------------------------------- 1 | 2 | textarea 3 | input 4 | .text 5 | border 1px solid #eee -------------------------------------------------------------------------------- /examples/images/jesus.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/stylus/master/examples/images/jesus.gif -------------------------------------------------------------------------------- /test/cases/compress.comments.styl: -------------------------------------------------------------------------------- 1 | // foo 2 | /* bar */ 3 | /*! baz */ 4 | body 5 | foo: 'bar' -------------------------------------------------------------------------------- /test/cases/conditional-assignment.css: -------------------------------------------------------------------------------- 1 | a.button { 2 | font: 14px; 3 | background: #fff; 4 | } -------------------------------------------------------------------------------- /test/cases/escape.css: -------------------------------------------------------------------------------- 1 | body { 2 | font: 14px + 1.2; 3 | border-radius: 5px 2px ( 5px 1px; 4 | } -------------------------------------------------------------------------------- /test/cases/escape.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | font 14px \+ 1.2 4 | border-radius 5px 2px \( 5px 1px 5 | -------------------------------------------------------------------------------- /test/cases/import.ordering/four.styl: -------------------------------------------------------------------------------- 1 | four 2 | foo bar 3 | 4 | @import "import.ordering/five" -------------------------------------------------------------------------------- /test/cases/regression.243.styl: -------------------------------------------------------------------------------- 1 | 2 | div.flash 3 | &.success + &.error 4 | color: red 5 | -------------------------------------------------------------------------------- /test/cases/rulset.newline.css: -------------------------------------------------------------------------------- 1 | textarea, 2 | input, 3 | .text { 4 | border: 1px solid #eee; 5 | } -------------------------------------------------------------------------------- /test/images/squirrel.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/stylus/master/test/images/squirrel.jpeg -------------------------------------------------------------------------------- /examples/images/gopher.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/stylus/master/examples/images/gopher.jpg -------------------------------------------------------------------------------- /examples/images/sprite.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/stylus/master/examples/images/sprite.gif -------------------------------------------------------------------------------- /test/cases/bifs.unit.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 20px; 3 | foo: 20px; 4 | foo: 20px; 5 | foo: 20%; 6 | } -------------------------------------------------------------------------------- /test/cases/important.css: -------------------------------------------------------------------------------- 1 | a { 2 | color: #f00 !important; 3 | } 4 | a.button { 5 | color: #00f; 6 | } -------------------------------------------------------------------------------- /test/cases/regression.139.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: bottom; 3 | foo: right; 4 | foo: bottom right; 5 | } -------------------------------------------------------------------------------- /test/cases/regression.220.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo-bar: bar; 3 | foo-bar: bar; 4 | foo-bar-: bar; 5 | } -------------------------------------------------------------------------------- /test/cases/regression.368.styl: -------------------------------------------------------------------------------- 1 | .small 2 | font: ((14px) / (2)) 3 | line-height: (2 / (1 * 2)) 4 | -------------------------------------------------------------------------------- /test/cases/if.else.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: string; 3 | foo: unit; 4 | foo: color; 5 | foo: unknown; 6 | } -------------------------------------------------------------------------------- /test/cases/regression.131.styl: -------------------------------------------------------------------------------- 1 | body { font-weight: normal; } /* foo */ 2 | body { color: #fff; } // foo -------------------------------------------------------------------------------- /test/cases/regression.137.styl: -------------------------------------------------------------------------------- 1 | 2 | #fea-ca 3 | padding 5px 4 | 5 | #ffffff 6 | padding 5px 7 | foo #fea-ca -------------------------------------------------------------------------------- /test/cases/regression.233.css: -------------------------------------------------------------------------------- 1 | button { 2 | foo: -1px; 3 | foo: 1px; 4 | foo: -1px; 5 | foo: 1px; 6 | } -------------------------------------------------------------------------------- /test/cases/regression.247.styl: -------------------------------------------------------------------------------- 1 | 2 | some #selector 3 | _display: inline 4 | 5 | foo 6 | _display inline 7 | -------------------------------------------------------------------------------- /test/cases/scope.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 24px; 3 | padding: 12px 5px 12px 5px; 4 | font-size: 50px; 5 | } -------------------------------------------------------------------------------- /test/cases/bifs.unquote.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: testing; 3 | background: testing; 4 | font: 14px / 1.5; 5 | } -------------------------------------------------------------------------------- /test/cases/coercion.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 10px; 3 | foo: 6px; 4 | foo: "foo bar"; 5 | foo: "value: 5px"; 6 | } -------------------------------------------------------------------------------- /test/cases/fontface.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Your typeface"; 3 | src: url("type/filename.eot"); 4 | } -------------------------------------------------------------------------------- /test/cases/functions.call.styl: -------------------------------------------------------------------------------- 1 | 2 | add(a, b) 3 | a + b 4 | 5 | body 6 | foo add(5, 10) 7 | foo add(5, 2) 8 | -------------------------------------------------------------------------------- /test/cases/import.index.css: -------------------------------------------------------------------------------- 1 | body { 2 | one: 1; 3 | } 4 | body { 5 | two: 2; 6 | } 7 | body { 8 | three: 3; 9 | } -------------------------------------------------------------------------------- /test/cases/keyframes.styl: -------------------------------------------------------------------------------- 1 | 2 | @-moz-keyframes foo 3 | from 4 | color: black 5 | to 6 | color: white 7 | -------------------------------------------------------------------------------- /test/cases/regression.131.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-weight: normal; 3 | } 4 | /* foo */ 5 | body { 6 | color: #fff; 7 | } -------------------------------------------------------------------------------- /test/cases/regression.233.styl: -------------------------------------------------------------------------------- 1 | 2 | n = 1px 3 | button 4 | foo: - n 5 | foo: n 6 | foo: - n 7 | foo: n 8 | -------------------------------------------------------------------------------- /test/cases/regression.247.css: -------------------------------------------------------------------------------- 1 | some #selector { 2 | _display: inline; 3 | } 4 | foo { 5 | _display: inline; 6 | } -------------------------------------------------------------------------------- /test/cases/coercion.styl: -------------------------------------------------------------------------------- 1 | body 2 | foo 5px + '5' 3 | foo 5px + '1 23' 4 | foo 'foo ' + 'bar' 5 | foo 'value: ' + 5px -------------------------------------------------------------------------------- /test/cases/fontface.styl: -------------------------------------------------------------------------------- 1 | 2 | @font-face 3 | font-family: "Your typeface" 4 | src: url("type/filename.eot") 5 | 6 | -------------------------------------------------------------------------------- /test/cases/import.complex.css: -------------------------------------------------------------------------------- 1 | one { 2 | foo: bar; 3 | } 4 | two { 5 | foo: bar; 6 | } 7 | three { 8 | foo: bar; 9 | } -------------------------------------------------------------------------------- /test/cases/introspection.css: -------------------------------------------------------------------------------- 1 | got { 2 | root: true; 3 | } 4 | body { 5 | got: "a mixin"; 6 | foo: "not a mixin"; 7 | } -------------------------------------------------------------------------------- /test/cases/literal.color.styl: -------------------------------------------------------------------------------- 1 | body 2 | color: #fc0 3 | color: #fc06 4 | color: #ffcc00 5 | color: #ffcc0066 6 | -------------------------------------------------------------------------------- /test/cases/mixins.return.styl: -------------------------------------------------------------------------------- 1 | another() 2 | foo bar 3 | bar baz 4 | return 5 | baz raz 6 | 7 | body 8 | another() -------------------------------------------------------------------------------- /test/cases/regression.220.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | {foo + '-' + bar}: bar 4 | {foo}-{bar}: bar 5 | {foo}-{bar}-: bar 6 | -------------------------------------------------------------------------------- /test/cases/self-assignment.styl: -------------------------------------------------------------------------------- 1 | color = white 2 | color = color is defined ? color : black 3 | body 4 | background color -------------------------------------------------------------------------------- /examples/literal.styl: -------------------------------------------------------------------------------- 1 | 2 | @css { 3 | body { 4 | font: 14px; 5 | } 6 | 7 | a { text-decoration: none; } 8 | } 9 | -------------------------------------------------------------------------------- /test/cases/bifs.dark.styl: -------------------------------------------------------------------------------- 1 | body 2 | foo dark(black) == true 3 | foo dark(#005716) == true 4 | foo dark(white) == false 5 | -------------------------------------------------------------------------------- /test/cases/bifs.light.styl: -------------------------------------------------------------------------------- 1 | body 2 | foo light(black) == false 3 | foo light(white) == true 4 | foo light(#00FF40) == true -------------------------------------------------------------------------------- /test/cases/bifs.unit.styl: -------------------------------------------------------------------------------- 1 | body 2 | foo unit(20, 'px') 3 | foo unit(20, px) 4 | foo unit(20%, px) 5 | foo unit(20, '%') -------------------------------------------------------------------------------- /test/cases/css.if.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #fff; 3 | color: #fff; 4 | } 5 | body { 6 | padding: 5px; 7 | margin: 5px; 8 | } -------------------------------------------------------------------------------- /test/cases/import.basic.css: -------------------------------------------------------------------------------- 1 | .a { 2 | color: #f00; 3 | } 4 | .b { 5 | color: #008000; 6 | } 7 | .c { 8 | color: #00f; 9 | } -------------------------------------------------------------------------------- /test/cases/regression.137.css: -------------------------------------------------------------------------------- 1 | #fea-ca { 2 | padding: 5px; 3 | } 4 | #ffffff { 5 | padding: 5px; 6 | foo: #fea -ca; 7 | } -------------------------------------------------------------------------------- /test/cases/regression.154.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: true; 3 | foo: false; 4 | } 5 | body { 6 | foo: false; 7 | foo: true; 8 | } -------------------------------------------------------------------------------- /test/cases/bifs.darken.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: #808080; 3 | foo: #000; 4 | } 5 | body { 6 | foo: #808080; 7 | foo: #404040; 8 | } -------------------------------------------------------------------------------- /test/cases/bifs.rgba.styl: -------------------------------------------------------------------------------- 1 | body 2 | background rgba(255,8,0,1) 3 | background rgba(255,255,0,0.2) 4 | background rgba(#fc0, 0.5) -------------------------------------------------------------------------------- /test/cases/import.mixins.styl: -------------------------------------------------------------------------------- 1 | 2 | if true 3 | @import "mixins/box" 4 | 5 | body 6 | pad 5px 10px 7 | 8 | form 9 | pad-x 5px -------------------------------------------------------------------------------- /test/cases/mixins.nested.css: -------------------------------------------------------------------------------- 1 | body { 2 | one: 1; 3 | two: 1 2; 4 | three: 1 2 3; 5 | -three: 1 2 c; 6 | -two: 1 b c; 7 | } -------------------------------------------------------------------------------- /test/cases/keyframes.css: -------------------------------------------------------------------------------- 1 | @-moz-keyframes foo { 2 | 0% { 3 | color: #000; 4 | } 5 | 6 | 100% { 7 | color: #fff; 8 | } 9 | } -------------------------------------------------------------------------------- /test/cases/regression.153.css: -------------------------------------------------------------------------------- 1 | #content { 2 | width: 960px; 3 | } 4 | @media screen { 5 | #content { 6 | width: 640px; 7 | } 8 | } -------------------------------------------------------------------------------- /test/cases/regression.270.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: url("/some/brown/white/icon.png"); 3 | color: #462323; 4 | color: #fff; 5 | } -------------------------------------------------------------------------------- /test/cases/scope.nested.css: -------------------------------------------------------------------------------- 1 | body { 2 | font: 5; 3 | } 4 | body .large { 5 | font: 10; 6 | } 7 | body .other { 8 | font: 15; 9 | } -------------------------------------------------------------------------------- /test/cases/bifs.last.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | nums = 1 2 3 4 4 | foo last(nums) == 4 5 | foo last(foo bar baz) == baz 6 | foo last(()) == null -------------------------------------------------------------------------------- /test/cases/bifs.rgba.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #ff0800; 3 | background: rgba(255,255,0,0.20); 4 | background: rgba(255,204,0,0.50); 5 | } -------------------------------------------------------------------------------- /test/cases/functions.multi-line.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 2 1; 3 | } 4 | body { 5 | padding: 2 1; 6 | } 7 | body { 8 | padding: 3 2; 9 | } -------------------------------------------------------------------------------- /test/cases/if.mixin.css: -------------------------------------------------------------------------------- 1 | body { 2 | got: above; 3 | got: below; 4 | got: empty; 5 | yup: just lots of empty; 6 | padding: 10px; 7 | } -------------------------------------------------------------------------------- /test/cases/import.mixins.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 10px 5px 10px 5px; 3 | } 4 | form { 5 | padding-left: 5px; 6 | padding-right: 5px; 7 | } -------------------------------------------------------------------------------- /test/cases/mixin.order.css: -------------------------------------------------------------------------------- 1 | body { 2 | one: 1; 3 | two: 2; 4 | three: 3; 5 | four: 4; 6 | five: 5; 7 | six: 6; 8 | seven: 7; 9 | } -------------------------------------------------------------------------------- /test/cases/regression.153.styl: -------------------------------------------------------------------------------- 1 | cols(n) 2 | width 160px * n 3 | 4 | #content 5 | cols 6 6 | 7 | @media screen 8 | #content 9 | cols 4 -------------------------------------------------------------------------------- /test/cases/regression.156.styl: -------------------------------------------------------------------------------- 1 | body 2 | mixin() 3 | 4 | body 5 | padding-{opposite-position(left)} 0 6 | float opposite-position(left) -------------------------------------------------------------------------------- /examples/import.styl: -------------------------------------------------------------------------------- 1 | 2 | @import "mixins/box" 3 | 4 | body 5 | pad 10px 5px 6 | 7 | body 8 | pad 5px 9 | 10 | body 11 | pad-x 5px -------------------------------------------------------------------------------- /test/cases/function.literals.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: bar(1px, baz(5px)); 3 | bar: baz(5px) baz(5px); 4 | foo: recurse; 5 | foo: recurse; 6 | } -------------------------------------------------------------------------------- /test/cases/properties.colons.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 5px; 3 | padding: 5px; 4 | foo: 5px; 5 | } 6 | body something { 7 | here: whoop; 8 | } -------------------------------------------------------------------------------- /test/cases/bifs.lookup.styl: -------------------------------------------------------------------------------- 1 | 2 | dark-blue = #006269 3 | 4 | dark(color-name) 5 | lookup('dark-' + color-name) 6 | 7 | body 8 | color dark('blue') -------------------------------------------------------------------------------- /test/cases/css.functions.single-line.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: false; 3 | foo: true; 4 | } 5 | body { 6 | foo: false; 7 | foo: true; 8 | foo: ; 9 | } -------------------------------------------------------------------------------- /test/cases/literal.color.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #fc0; 3 | color: rgba(255,204,0,0.40); 4 | color: #fc0; 5 | color: rgba(255,204,0,0.40); 6 | } 7 | -------------------------------------------------------------------------------- /test/cases/mixin.order.nested.css: -------------------------------------------------------------------------------- 1 | body { 2 | one: 1; 3 | two: 2; 4 | three: 3; 5 | four: 4; 6 | five: 5; 7 | six: 6; 8 | seven: 7; 9 | } -------------------------------------------------------------------------------- /test/cases/regression.260.css: -------------------------------------------------------------------------------- 1 | tr td.currency_no_total, 2 | tr td.number_no_total, 3 | tr td.number, 4 | tr td.currency { 5 | text-align: right; 6 | } -------------------------------------------------------------------------------- /test/cases/regression.260.styl: -------------------------------------------------------------------------------- 1 | tr 2 | td.currency_no_total 3 | td.number_no_total 4 | td.number 5 | td.currency 6 | text-align right 7 | -------------------------------------------------------------------------------- /test/cases/regression.270.styl: -------------------------------------------------------------------------------- 1 | 2 | brown = #462323 3 | 4 | body 5 | background: url(/some/brown/white/icon.png) 6 | color: brown 7 | color: white -------------------------------------------------------------------------------- /test/cases/bifs.opposite-position.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: ; 3 | foo: true; 4 | foo: true; 5 | foo: true; 6 | foo: true; 7 | foo: bottom right; 8 | } -------------------------------------------------------------------------------- /test/cases/compress.units.css: -------------------------------------------------------------------------------- 1 | body{foo:0;foo:0;foo:15;foo:-15;foo:15px;foo:-15px} 2 | body{foo:.1;foo:-.1;foo:1.1;foo:-1.1;foo:.1;foo:-.1;foo:10.1;foo:-10.1} -------------------------------------------------------------------------------- /test/cases/keyframes.fabrication.defaults.styl: -------------------------------------------------------------------------------- 1 | 2 | @keyframes foo { 3 | from { 4 | color: black 5 | } 6 | to { 7 | color: white 8 | } 9 | } -------------------------------------------------------------------------------- /test/cases/bifs.length.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 0; 3 | foo: 1; 4 | foo: 1; 5 | foo: 2; 6 | foo: 3; 7 | foo: 4; 8 | foo: 5; 9 | foo: 6; 10 | } -------------------------------------------------------------------------------- /test/cases/functions.nested-calls.styl: -------------------------------------------------------------------------------- 1 | 2 | sub(a, b) 3 | a - b 4 | 5 | add(a, b) 6 | a + b 7 | 8 | body 9 | foo add(5, add(5, sub(5, 2))) 10 | -------------------------------------------------------------------------------- /test/cases/mixins.conditional.styl: -------------------------------------------------------------------------------- 1 | overload-padding = true 2 | 3 | if overload-padding 4 | padding(y, x) 5 | margin y x 6 | 7 | body 8 | padding 5px 10px -------------------------------------------------------------------------------- /test/cases/operators.complex.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: yes; 3 | foo: true; 4 | foo: yay; 5 | foo: nah; 6 | foo: nah; 7 | foo: true; 8 | foo: false; 9 | } -------------------------------------------------------------------------------- /test/cases/regression.248.compressed.css: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes colors{0%{background-color:#f00} 2 | 15%{background-color:#00f} 3 | 100%{background-color:#000} 4 | } -------------------------------------------------------------------------------- /test/cases/bifs.image-size.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 315px 450px; 3 | foo: true; 4 | foo: true; 5 | } 6 | body { 7 | foo: 400px 479px; 8 | foo: 400px 479px; 9 | } -------------------------------------------------------------------------------- /test/cases/functions.nested.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 3.5; 3 | } 4 | body { 5 | padding: 3.5; 6 | } 7 | body { 8 | padding: 10; 9 | padding: 0; 10 | } -------------------------------------------------------------------------------- /test/cases/functions.arg-calls.styl: -------------------------------------------------------------------------------- 1 | add(a, b) 2 | a + b 3 | 4 | pad(x, y = x) 5 | padding y x y x 6 | 7 | form input 8 | n = 5 9 | pad(5px, unit(add(n, n), 'px')) -------------------------------------------------------------------------------- /test/cases/properties.colons.styl: -------------------------------------------------------------------------------- 1 | 2 | mixin() 3 | foo: 5px 4 | something 5 | here: whoop 6 | 7 | body 8 | margin: 5px 9 | padding: 5px 10 | mixin() -------------------------------------------------------------------------------- /test/cases/regression.235.css: -------------------------------------------------------------------------------- 1 | foo { 2 | -bar: baz; 3 | } 4 | foo { 5 | -bar: baz; 6 | } 7 | body { 8 | -webkit: foo; 9 | -moz: foo; 10 | -o: foo; 11 | } -------------------------------------------------------------------------------- /test/cases/selectors.nested.comma.styl: -------------------------------------------------------------------------------- 1 | #container, #footer 2 | .hide 3 | display none 4 | 5 | #foo, #bar, #baz 6 | .hide 7 | .stuff 8 | display none 9 | -------------------------------------------------------------------------------- /test/cases/conditional-assignment.styl: -------------------------------------------------------------------------------- 1 | 2 | color ?= white 3 | color ?= black 4 | 5 | font-size ?= 14px 6 | 7 | a.button 8 | font font-size 9 | background color 10 | -------------------------------------------------------------------------------- /test/cases/regression.216.styl: -------------------------------------------------------------------------------- 1 | 2 | @media only screen and (width-max: 767px) 3 | article > div 4 | width 192px 5 | 6 | @media print 7 | * .no-print 8 | display none 9 | -------------------------------------------------------------------------------- /examples/basic.styl: -------------------------------------------------------------------------------- 1 | body a 2 | font 12px/1.3 "Lucida Grande", Arial, sans-serif 3 | background black 4 | color #ccc 5 | 6 | form input 7 | padding 5px 8 | border 1px solid 9 | -------------------------------------------------------------------------------- /test/cases/functions.variable.css: -------------------------------------------------------------------------------- 1 | body { 2 | font: 28px; 3 | padding-left: 5px; 4 | padding-right: 5px; 5 | } 6 | form { 7 | padding-top: 10px; 8 | padding-bottom: 10px; 9 | } -------------------------------------------------------------------------------- /test/cases/functions.variable.ident.styl: -------------------------------------------------------------------------------- 1 | 2 | add(a, b) 3 | a + b 4 | 5 | size-function = add 6 | 7 | size(n) 8 | size-function(n, n) 9 | 10 | body 11 | font size(14px) -------------------------------------------------------------------------------- /test/cases/mixins.order.2.css: -------------------------------------------------------------------------------- 1 | body { 2 | one: 1; 3 | two: 2; 4 | three: 3; 5 | four: 4; 6 | five: 5; 7 | six: 6; 8 | seven: 7; 9 | eight: 8; 10 | nine: 9; 11 | } -------------------------------------------------------------------------------- /test/cases/bifs.match.styl: -------------------------------------------------------------------------------- 1 | pad(type = padding) 2 | if match('^pad', type) 3 | padding 5px 4 | else 5 | margin 5px 6 | 7 | body 8 | pad(margin) 9 | pad(padding) 10 | -------------------------------------------------------------------------------- /test/cases/bifs.unquote.styl: -------------------------------------------------------------------------------- 1 | 2 | line-height(n) 3 | unquote('/ ' + n) 4 | 5 | body 6 | background unquote(testing) 7 | background unquote('testing') 8 | font 14px line-height(1.5) 9 | -------------------------------------------------------------------------------- /test/cases/keyframes.fabrication.styl: -------------------------------------------------------------------------------- 1 | 2 | vendors = moz official 3 | 4 | @keyframes foo { 5 | from { 6 | color: black 7 | } 8 | to { 9 | color: white 10 | } 11 | } -------------------------------------------------------------------------------- /test/cases/scope.nested.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | size = 5 4 | font size 5 | .large 6 | large = size * 2 7 | font large 8 | .other 9 | large ?= size * 3 10 | font large -------------------------------------------------------------------------------- /test/cases/import.ordering.styl: -------------------------------------------------------------------------------- 1 | 2 | dir = 'import.ordering' 3 | 4 | one 5 | foo bar 6 | 7 | @import dir + "/two" 8 | 9 | three 10 | foo bar 11 | 12 | @import dir + '/four' 13 | -------------------------------------------------------------------------------- /test/cases/literal.css: -------------------------------------------------------------------------------- 1 | body { 2 | font: 14px; 3 | } 4 | 5 | a { text-decoration: none; } 6 | #login { 7 | border-radius: /; 8 | border-radius: true; 9 | border-radius: true; 10 | } -------------------------------------------------------------------------------- /test/cases/mixin.order.conditional.css: -------------------------------------------------------------------------------- 1 | body { 2 | one: 1; 3 | two: 2; 4 | three: 3; 5 | four: 4; 6 | five: 5; 7 | six: 6; 8 | seven: 7; 9 | eight: 8; 10 | nine: 9; 11 | } -------------------------------------------------------------------------------- /test/cases/selectors.nested.comma.css: -------------------------------------------------------------------------------- 1 | #container .hide, 2 | #footer .hide { 3 | display: none; 4 | } 5 | #foo .hide .stuff, 6 | #bar .hide .stuff, 7 | #baz .hide .stuff { 8 | display: none; 9 | } -------------------------------------------------------------------------------- /examples/gradients.styl: -------------------------------------------------------------------------------- 1 | 2 | @import 'mixins/gradients' 3 | 4 | #box { 5 | border: 1px solid #eee; 6 | padding: 150px; 7 | background: linear-gradient(top, white, 10% red, 90% blue, black); 8 | } -------------------------------------------------------------------------------- /test/cases/functions.return.each.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: "1 2 3"; 3 | foo: "1, 2, 3"; 4 | foo: "1,2,3"; 5 | } 6 | body { 7 | foo: "1 2 3"; 8 | foo: "1, 2, 3"; 9 | foo: "1,2,3"; 10 | } -------------------------------------------------------------------------------- /test/cases/properties.one-line.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #00f; 3 | width: 100px; 4 | height: 50px; 5 | } 6 | body { 7 | background: #00f; 8 | width: 100px; 9 | height: 50px; 10 | } -------------------------------------------------------------------------------- /test/cases/properties.one-line.styl: -------------------------------------------------------------------------------- 1 | bg() 2 | background: blue; 3 | 4 | body { 5 | bg(); width: 100px; 6 | height: 50px; 7 | } 8 | 9 | body 10 | bg(); width 100px; 11 | height 50px -------------------------------------------------------------------------------- /test/cases/regression.235.styl: -------------------------------------------------------------------------------- 1 | 2 | foo 3 | -{bar}: baz 4 | 5 | mixin() 6 | -{bar}: baz 7 | 8 | foo 9 | mixin() 10 | 11 | body 12 | for vendor in webkit moz o 13 | -{vendor}: foo -------------------------------------------------------------------------------- /test/cases/regression.272.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 1 1 "+"; 3 | foo: 1 5 "+"; 4 | foo: 1 5 "-"; 5 | } 6 | body { 7 | foo: 1; 8 | foo: 1 2; 9 | foo: 1 2 3; 10 | foo: 1 2 3 4 5 6; 11 | } -------------------------------------------------------------------------------- /test/cases/bifs.components.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: 255; 3 | background: 204; 4 | background: 0; 5 | background: 0.4; 6 | background: 15deg; 7 | background: 100%; 8 | background: 60%; 9 | } -------------------------------------------------------------------------------- /test/cases/import.ordering.css: -------------------------------------------------------------------------------- 1 | one { 2 | foo: bar; 3 | } 4 | two { 5 | foo: bar; 6 | } 7 | three { 8 | foo: bar; 9 | } 10 | four { 11 | foo: bar; 12 | } 13 | five { 14 | foo: bar; 15 | } -------------------------------------------------------------------------------- /test/cases/mixins/box.styl: -------------------------------------------------------------------------------- 1 | 2 | pad(x, y = x) 3 | padding y x y x 4 | 5 | pad-x(n) 6 | padding-left n 7 | padding-right n 8 | 9 | pad-y(n) 10 | padding-top n 11 | padding-bottom n 12 | -------------------------------------------------------------------------------- /test/cases/operators.mixins.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: false; 3 | foo: true; 4 | foo: true; 5 | foo: false; 6 | foo: false; 7 | foo: "something"; 8 | foo: "something"; 9 | foo: "12"; 10 | } -------------------------------------------------------------------------------- /test/cases/bifs.darken.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | foo: darken(#fff, 50) 4 | foo: darken(darken(#fff, 50), 50) 5 | 6 | 7 | body 8 | foo: darken(#fff, 50%) 9 | foo: darken(darken(#fff, 50%), 50%) 10 | -------------------------------------------------------------------------------- /test/cases/bifs.join.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: "1 2 3"; 3 | foo: "1, 2, 3"; 4 | foo: "1,2,3"; 5 | foo: "1"; 6 | foo: true; 7 | } 8 | body { 9 | foo: "1, 2, 3"; 10 | foo: "one, two, three"; 11 | } -------------------------------------------------------------------------------- /test/cases/functions.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 10px 5px 10px 5px; 3 | } 4 | form .button { 5 | padding-left: 15px; 6 | } 7 | body { 8 | foo: bottom; 9 | foo: right; 10 | foo: bottom right; 11 | } -------------------------------------------------------------------------------- /test/cases/operators.assignment.function.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 20; 3 | } 4 | body { 5 | foo: 5; 6 | } 7 | body { 8 | foo: 20; 9 | } 10 | body { 11 | foo: 2.5; 12 | } 13 | body { 14 | foo: 1; 15 | } -------------------------------------------------------------------------------- /test/cases/operators.assignment.mixin.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 20; 3 | } 4 | body { 5 | foo: 5; 6 | } 7 | body { 8 | foo: 20; 9 | } 10 | body { 11 | foo: 2.5; 12 | } 13 | body { 14 | foo: 1; 15 | } -------------------------------------------------------------------------------- /test/cases/regression.130.styl: -------------------------------------------------------------------------------- 1 | 2 | body { font: 13px / 1.231; } 3 | body {font: 13px / 1.231;} 4 | body {font: 13px / 1.231} 5 | body { font : 13px / 1.231 } 6 | body { font : 13px / 1.231; background: white } 7 | -------------------------------------------------------------------------------- /test/cases/regression.216.css: -------------------------------------------------------------------------------- 1 | @media only screen and (width-max: 767px) { 2 | article > div { 3 | width: 192px; 4 | } 5 | } 6 | @media print { 7 | * .no-print { 8 | display: none; 9 | } 10 | } -------------------------------------------------------------------------------- /test/cases/function.literals.styl: -------------------------------------------------------------------------------- 1 | 2 | something(arg) 3 | bar arg arg 4 | 5 | recurse() 6 | foo recurse 7 | foo recurse 8 | 9 | body 10 | foo bar(1px, baz(5px)) 11 | something(baz(5px)) 12 | recurse() -------------------------------------------------------------------------------- /test/cases/page.styl: -------------------------------------------------------------------------------- 1 | 2 | @page 3 | margin 2.5cm 4 | 5 | @page :left 6 | margin-left 5cm 7 | 8 | @page :right 9 | margin-right 5cm 10 | 11 | @page :first 12 | margin-top 8cm 13 | background white 14 | -------------------------------------------------------------------------------- /test/cases/regression.229.styl: -------------------------------------------------------------------------------- 1 | body 2 | font 14px helvetica, arial, sans-serif 3 | background #cdcdcd 4 | padding 20px 5 | h1 6 | color #2e66f5 7 | font-size 50px 8 | p 9 | margin 15px 0 10 | -------------------------------------------------------------------------------- /test/cases/scope.styl: -------------------------------------------------------------------------------- 1 | 2 | size = 12px 3 | size-large = size * 2 4 | 5 | pad(x, y = size) 6 | margin size-large 7 | padding y x y x 8 | 9 | body 10 | size = 50px 11 | pad(5px) 12 | font-size size 13 | -------------------------------------------------------------------------------- /test/cases/regression.248.compressed.styl: -------------------------------------------------------------------------------- 1 | 2 | vendors = webkit 3 | 4 | @keyframes colors 5 | 0% 6 | background-color red 7 | 15% 8 | background-color blue 9 | 100% 10 | background-color black 11 | -------------------------------------------------------------------------------- /docs/textmate.md: -------------------------------------------------------------------------------- 1 | 2 | ## TextMate Bundle 3 | 4 | Stylus ships with a TextMate bundle, located within `./editors`. To install simply execute `make install-bundle`, or place `./editors/Stylus.tmbundle` in the appropriate location. -------------------------------------------------------------------------------- /test/cases/operators.subscript.range.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: a b; 3 | foo: a b c; 4 | foo: d e f; 5 | foo: c d e; 6 | } 7 | body { 8 | foo: 1 2 3 4; 9 | } 10 | body { 11 | foo: ; 12 | foo: ; 13 | foo: ; 14 | } -------------------------------------------------------------------------------- /test/cases/scope.complex.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 24px; 3 | padding: 12px 5px 12px 5px; 4 | font-size: 50px; 5 | } 6 | form input { 7 | border: 3px solid #000; 8 | margin: 24px; 9 | padding: 2px 1px 2px 1px; 10 | } -------------------------------------------------------------------------------- /test/cases/functions.property.styl: -------------------------------------------------------------------------------- 1 | 2 | border-radius(size) 3 | -webkit-border-radius size 4 | -moz-border-radius size 5 | border-radius size 6 | 7 | form 8 | border-radius 5px 9 | 10 | a.button 11 | border-radius 5px -------------------------------------------------------------------------------- /test/cases/mixins.nested.styl: -------------------------------------------------------------------------------- 1 | 2 | one(a) 3 | one a 4 | two(b) 5 | two a b 6 | three(c) 7 | three a b c 8 | three(3) 9 | -three a b c 10 | two(2) 11 | -two a b c 12 | 13 | body 14 | one(1) 15 | -------------------------------------------------------------------------------- /test/cases/page.css: -------------------------------------------------------------------------------- 1 | @page { 2 | margin: 2.5cm; 3 | } 4 | @page :left { 5 | margin-left: 5cm; 6 | } 7 | @page :right { 8 | margin-right: 5cm; 9 | } 10 | @page :first { 11 | margin-top: 8cm; 12 | background: white; 13 | } -------------------------------------------------------------------------------- /test/cases/media.styl: -------------------------------------------------------------------------------- 1 | 2 | @media print and (width: 21cm) and (height: 29cm) 3 | body 4 | margin 3cm 5 | padding 0 6 | 7 | @media print 8 | @page :left 9 | margin-left 5px 10 | @page :right 11 | margin-right 5px -------------------------------------------------------------------------------- /test/cases/bifs.lighten.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: #808080; 3 | foo: #fff; 4 | } 5 | body { 6 | foo: #808080; 7 | foo: #c0c0c0; 8 | } 9 | body { 10 | foo: #ababab; 11 | foo: #dfdfdf; 12 | foo: #ababab; 13 | foo: #d5d5d5; 14 | } -------------------------------------------------------------------------------- /test/cases/function.arguments.styl: -------------------------------------------------------------------------------- 1 | 2 | sum() 3 | n = 0 4 | for num in arguments 5 | n = n + num 6 | n 7 | 8 | test(a, b) 9 | a = b 10 | (arguments[0] a) 11 | 12 | body 13 | padding sum(1,2,3,4,5) 14 | padding test(1,2) -------------------------------------------------------------------------------- /test/cases/introspection.styl: -------------------------------------------------------------------------------- 1 | reset() 2 | if mixin == 'root' 3 | got 4 | root true 5 | else if mixin 6 | got 'a mixin' 7 | else 8 | 'not a mixin' 9 | 10 | reset() 11 | 12 | body 13 | reset() 14 | foo reset() -------------------------------------------------------------------------------- /examples/mixins/box.styl: -------------------------------------------------------------------------------- 1 | 2 | pad(x, y = x) 3 | if y == x 4 | padding y 5 | else 6 | padding y x y x 7 | 8 | pad-x(n) 9 | padding-left n 10 | padding-right n 11 | 12 | pad-y(n) 13 | padding-top n 14 | padding-bottom n 15 | -------------------------------------------------------------------------------- /test/cases/css.functions.single-line.styl: -------------------------------------------------------------------------------- 1 | 2 | large(n){ n > 100 } 3 | 4 | body 5 | foo large(5) 6 | foo large(300) 7 | 8 | large(n){ n > 100 if n is a 'unit' } 9 | 10 | body 11 | foo large(5) 12 | foo large(300) 13 | foo large('test') -------------------------------------------------------------------------------- /test/cases/functions.property.css: -------------------------------------------------------------------------------- 1 | form { 2 | -webkit-border-radius: 5px; 3 | -moz-border-radius: 5px; 4 | border-radius: 5px; 5 | } 6 | a.button { 7 | -webkit-border-radius: 5px; 8 | -moz-border-radius: 5px; 9 | border-radius: 5px; 10 | } -------------------------------------------------------------------------------- /test/cases/functions.return.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: no; 3 | foo: yes; 4 | foo: false; 5 | foo: yes; 6 | foo: "a is not a unit"; 7 | foo: 2; 8 | } 9 | body { 10 | foo: five; 11 | foo: something; 12 | } 13 | body { 14 | foo: 3; 15 | } -------------------------------------------------------------------------------- /test/cases/regression.229.css: -------------------------------------------------------------------------------- 1 | body { 2 | font: 14px helvetica, arial, sans-serif; 3 | background: #cdcdcd; 4 | padding: 20px; 5 | } 6 | body h1 { 7 | color: #2e66f5; 8 | font-size: 50px; 9 | } 10 | body p { 11 | margin: 15px 0; 12 | } -------------------------------------------------------------------------------- /test/cases/regression.252.css: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes movingBorder { 2 | 0% { 3 | border-radius: 0 0 0 35px; 4 | } 5 | 6 | 50% { 7 | border-radius: 0 0 25px 0; 8 | } 9 | 10 | 100% { 11 | border-radius: 0 25px 0 0; 12 | } 13 | } -------------------------------------------------------------------------------- /test/cases/bifs.s.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: bar(); 3 | foo: bar("baz"); 4 | foo: bar(baz); 5 | foo: bar(15px); 6 | foo: rgba(255, 100, 50, 0.5); 7 | foo: bar(%Z); 8 | foo: bar(15px, ); 9 | foo: bar(foo bar, 1 2 3); 10 | foo: bar(#eee); 11 | } -------------------------------------------------------------------------------- /test/cases/css.media.css: -------------------------------------------------------------------------------- 1 | @media print { 2 | body { 3 | margin: 5px; 4 | padding: 5px; 5 | } 6 | } 7 | @media print { 8 | body { 9 | margin: 5px; 10 | padding: 5px; 11 | } 12 | .no-print { 13 | display: none; 14 | } 15 | } -------------------------------------------------------------------------------- /test/cases/operators.assignment.root.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 20; 3 | foo: 21; 4 | } 5 | body { 6 | foo: 20; 7 | } 8 | body { 9 | foo: 5; 10 | } 11 | body { 12 | foo: 20; 13 | } 14 | body { 15 | foo: 2.5; 16 | } 17 | body { 18 | foo: 1; 19 | } -------------------------------------------------------------------------------- /test/cases/regression.154.styl: -------------------------------------------------------------------------------- 1 | 2 | light(color) 3 | lightness(color) >= 50% 4 | 5 | dark(color) 6 | lightness(color) < 50% 7 | 8 | body 9 | foo light(white) 10 | foo light(black) 11 | 12 | body 13 | foo dark(white) 14 | foo dark(black) -------------------------------------------------------------------------------- /test/cases/regression.274.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: true; 3 | foo: true; 4 | foo: false; 5 | foo: true; 6 | foo: true; 7 | foo: false; 8 | foo: false; 9 | foo: "ok"; 10 | foo: "ok"; 11 | foo: true; 12 | foo: false; 13 | foo: true; 14 | } -------------------------------------------------------------------------------- /examples/nesting.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | background #ccc 4 | color #000 5 | 6 | form 7 | .buttons 8 | margin 10px 0 9 | padding 5px 10 | [type=submit] 11 | padding 5px 12 | border none 13 | input 14 | border 1px solid #ccc 15 | -------------------------------------------------------------------------------- /test/cases/bifs.join.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | foo join(' ', 1 2 3) 4 | foo join(', ', 1 2 3) 5 | foo join(',', 1 2 3) 6 | foo join(',', 1) 7 | foo join(',') == null 8 | 9 | body 10 | foo join(', ', 1, 2, 3) 11 | foo join(', ', one 1, two 2, three 3) -------------------------------------------------------------------------------- /test/cases/mixin.order.styl: -------------------------------------------------------------------------------- 1 | mixin2() 2 | three 3 3 | 4 | mixin3() 5 | four 4 6 | mixin4() 7 | 8 | mixin4() 9 | five 5 10 | 11 | mixin() 12 | two 2 13 | mixin2() 14 | mixin3() 15 | six 6 16 | 17 | body 18 | one 1 19 | mixin() 20 | seven 7 -------------------------------------------------------------------------------- /test/cases/regression.130.css: -------------------------------------------------------------------------------- 1 | body { 2 | font: 13px/1.231; 3 | } 4 | body { 5 | font: 13px/1.231; 6 | } 7 | body { 8 | font: 13px/1.231; 9 | } 10 | body { 11 | font: 13px/1.231; 12 | } 13 | body { 14 | font: 13px/1.231; 15 | background: #fff; 16 | } -------------------------------------------------------------------------------- /test/cases/compress.units.styl: -------------------------------------------------------------------------------- 1 | body 2 | foo 0 3 | foo 0px 4 | foo 15 5 | foo -15 6 | foo 15px 7 | foo -15px 8 | 9 | body 10 | foo 0.1 11 | foo -0.1 12 | foo 1.1 13 | foo -1.1 14 | foo 0.1 15 | foo -0.1 16 | foo 10.1 17 | foo -10.1 18 | -------------------------------------------------------------------------------- /test/cases/css.media.styl: -------------------------------------------------------------------------------- 1 | 2 | @media print { 3 | body { 4 | margin: 5px; 5 | padding: 5px; 6 | } 7 | } 8 | 9 | @media print { 10 | body { 11 | margin: 5px; 12 | padding: 5px; 13 | } 14 | .no-print { 15 | display: none; 16 | } 17 | } -------------------------------------------------------------------------------- /test/cases/mixins.complex.fix-to.css: -------------------------------------------------------------------------------- 1 | .button { 2 | position: fixed; 3 | bottom: 0; 4 | left: 0; 5 | } 6 | .button { 7 | position: fixed; 8 | bottom: 0; 9 | left: 0; 10 | } 11 | .button { 12 | position: fixed; 13 | bottom: 5px; 14 | left: 5px; 15 | } -------------------------------------------------------------------------------- /test/cases/mixins.order.2.styl: -------------------------------------------------------------------------------- 1 | test-nested() 2 | two 2 3 | if true 4 | three 3 5 | if true 6 | four 4 7 | if true 8 | five 5 9 | six 6 10 | seven 7 11 | eight 8 12 | 13 | body 14 | one 1 15 | test-nested() 16 | nine 9 17 | -------------------------------------------------------------------------------- /test/cases/operator.range.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 1 2 3 4 5; 3 | foo: 1 2 3 4 5 6 7 8 9 10; 4 | foo: 1; 5 | foo: 1 2 3 4 5; 6 | foo: 5; 7 | foo: 2; 8 | foo: 5; 9 | foo: 6 7 8 9 10; 10 | foo: true; 11 | foo: true; 12 | } 13 | body { 14 | foo: 1 2 3; 15 | } -------------------------------------------------------------------------------- /test/cases/comments.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #f00; 3 | } 4 | form { 5 | background: #fff; 6 | } 7 | /* 8 | 9 | body 10 | a 11 | color blue 12 | 13 | */ 14 | html>/**/body select, 15 | x:-moz-any-link, 16 | x:default select { 17 | font-weight: bold !important; 18 | } -------------------------------------------------------------------------------- /test/cases/functions.defaults.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 15px 5px 15px 5px; 3 | } 4 | a.button { 5 | padding: 10px 10px 10px 10px; 6 | } 7 | a.button-2 { 8 | padding: 2px 10px 2px 10px; 9 | } 10 | body { 11 | padding: 10px; 12 | } 13 | .button { 14 | padding: 5px; 15 | } -------------------------------------------------------------------------------- /test/cases/keyframes.fabrication.css: -------------------------------------------------------------------------------- 1 | @-moz-keyframes foo { 2 | 0% { 3 | color: #000; 4 | } 5 | 6 | 100% { 7 | color: #fff; 8 | } 9 | } 10 | @keyframes foo { 11 | 0% { 12 | color: #000; 13 | } 14 | 15 | 100% { 16 | color: #fff; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/cases/media.css: -------------------------------------------------------------------------------- 1 | @media print and (width: 21cm) and (height: 29cm) { 2 | body { 3 | margin: 3cm; 4 | padding: 0; 5 | } 6 | } 7 | @media print { 8 | @page :left { 9 | margin-left: 5px; 10 | } 11 | @page :right { 12 | margin-right: 5px; 13 | } 14 | } -------------------------------------------------------------------------------- /test/cases/mixin.order.nested.styl: -------------------------------------------------------------------------------- 1 | 2 | mixin2() 3 | three 3 4 | 5 | mixin3() 6 | four 4 7 | mixin4() 8 | 9 | mixin4() 10 | five 5 11 | 12 | mixin() 13 | two 2 14 | mixin2() 15 | mixin3() 16 | six 6 17 | 18 | body 19 | one 1 20 | mixin() 21 | seven 7 -------------------------------------------------------------------------------- /test/cases/regression.360.styl: -------------------------------------------------------------------------------- 1 | .clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .clearfix { display: inline-block; } /* Hide from IE Mac \*/ .clearfix { display: block; } /* End hide from IE Mac */ .none { display: none; } /* End Clearfix */ -------------------------------------------------------------------------------- /test/cases/variables.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: 204; 3 | } 4 | body { 5 | font: 14px "Lucida Grande", Arial, sans-serif; 6 | padding: 5px; 7 | margin: 5px; 8 | } 9 | a { 10 | font: 11px Impact, "Lucida Grande", Arial, sans-serif, serif; 11 | border: 1px solid #fff; 12 | } -------------------------------------------------------------------------------- /test/cases/bifs.type.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: "string"; 3 | background: "unit"; 4 | background: "unit"; 5 | background: "hsla"; 6 | background: "rgba"; 7 | background: "ident"; 8 | background: "unit"; 9 | background: "function"; 10 | background: "ident"; 11 | } -------------------------------------------------------------------------------- /test/cases/functions.multiple-calls.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 5px; 3 | padding: 100px; 4 | padding: 10px; 5 | padding: 1px; 6 | padding: 100px; 7 | } 8 | form { 9 | padding-left: 5px; 10 | padding-right: 5px; 11 | padding-top: 10px; 12 | padding-bottom: 10px; 13 | } -------------------------------------------------------------------------------- /test/cases/if.selectors.css: -------------------------------------------------------------------------------- 1 | form input { 2 | border: 1px solid #eee; 3 | } 4 | [type="text"] { 5 | margin: 0; 6 | } 7 | input[type="text"] { 8 | display: none; 9 | } 10 | input[type="password"], 11 | select { 12 | background: #eee; 13 | } 14 | body { 15 | font: 12px; 16 | } -------------------------------------------------------------------------------- /test/cases/regression.107.lookup-failure.css: -------------------------------------------------------------------------------- 1 | button { 2 | background: #e3e3e3; 3 | } 4 | button:hover { 5 | background: #dbdbdb; 6 | } 7 | button:active { 8 | background: #d6d6d6; 9 | } 10 | button nested really-nested with-even-more-nesting { 11 | background: #e3e3e3; 12 | } -------------------------------------------------------------------------------- /test/cases/regression.212.css: -------------------------------------------------------------------------------- 1 | button { 2 | intensity: 1; 3 | background: #eee; 4 | glow: "glow"; 5 | } 6 | button { 7 | intensity: 0.5; 8 | background: #333; 9 | glow: "glow"; 10 | } 11 | button { 12 | intensity: 0.5; 13 | background: #000; 14 | glow: "glow"; 15 | } -------------------------------------------------------------------------------- /examples/comments.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/comments.styl', 'utf8'); 8 | 9 | css.render(str, { filename: 'comments.styl' }, function(err, css){ 10 | console.log(css); 11 | }); -------------------------------------------------------------------------------- /test/cases/operators.subscript.range.styl: -------------------------------------------------------------------------------- 1 | body 2 | vals = a b c d e f g 3 | foo vals[0...2] 4 | foo vals[0..2] 5 | foo vals[3..5] 6 | foo vals[2 3 4] 7 | 8 | body 9 | vals = (1 2) (3 4) 10 | foo vals[0..1] 11 | 12 | body 13 | foo ()[] 14 | foo ()[1] 15 | foo ()[1..3] -------------------------------------------------------------------------------- /test/cases/scope.complex.styl: -------------------------------------------------------------------------------- 1 | 2 | size = 12px 3 | size-large = size * 2 4 | 5 | pad(x, y = size) 6 | margin size-large 7 | padding y x y x 8 | 9 | body 10 | size = 50px 11 | pad(5px) 12 | font-size size 13 | 14 | form input 15 | border (size / 4) solid black 16 | pad(1px, 2px) -------------------------------------------------------------------------------- /test/cases/bifs.components.styl: -------------------------------------------------------------------------------- 1 | body 2 | background red(#fc0) 3 | background green(#fc0) 4 | background blue(#fc0) 5 | background alpha(#fff - rgba(0,0,0,.6)) 6 | 7 | background hue(hsl(15deg,100%,60%)) 8 | background saturation(hsl(15deg,100%,60%)) 9 | background lightness(hsl(15deg,100%,60%)) -------------------------------------------------------------------------------- /examples/basic.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/basic.styl', 'utf8'); 8 | 9 | css.render(str, { filename: 'basic.styl' }, function(err, css){ 10 | if (err) throw err; 11 | console.log(css); 12 | }); -------------------------------------------------------------------------------- /test/cases/bifs.opposite-position.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | foo opposite-position() 4 | foo opposite-position(top) == bottom 5 | foo opposite-position(left) == right 6 | foo opposite-position(top left)[0] == bottom 7 | foo opposite-position(top left)[1] == right 8 | val = top left 9 | foo opposite-position(val) -------------------------------------------------------------------------------- /examples/comments.styl: -------------------------------------------------------------------------------- 1 | 2 | // This is a comment 3 | body 4 | color white 5 | // You can nest them as you wish 6 | // and have more comments 7 | // and more! 8 | 9 | /* 10 | We can also use multi-line comments 11 | like this, which are native to css 12 | */ 13 | 14 | form 15 | /* color black */ 16 | -------------------------------------------------------------------------------- /examples/literal.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/literal.styl', 'utf8'); 8 | 9 | css.render(str, { filename: 'literal.styl' }, function(err, css){ 10 | if (err) throw err; 11 | console.log(css); 12 | }); -------------------------------------------------------------------------------- /examples/nesting.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/nesting.styl', 'utf8'); 8 | 9 | css.render(str, { filename: 'nesting.styl' }, function(err, css){ 10 | if (err) throw err; 11 | console.log(css); 12 | }); -------------------------------------------------------------------------------- /test/cases/functions.multi-line.styl: -------------------------------------------------------------------------------- 1 | 2 | pad( 3 | x = 5 4 | , y = 10 5 | ) 6 | padding y x 7 | 8 | body 9 | pad 1 2 10 | 11 | pad( 12 | x = 5 13 | , y = 10 14 | ) 15 | padding y x 16 | 17 | body 18 | pad 1 2 19 | 20 | body 21 | pad(x 22 | , y 23 | ) 24 | padding y x 25 | pad 2 3 -------------------------------------------------------------------------------- /test/cases/mixin.order.conditional.styl: -------------------------------------------------------------------------------- 1 | mixin2() 2 | four 4 3 | if true 4 | five 5 5 | 6 | mixin() 7 | mixin2() 8 | if true 9 | six 6 10 | if true 11 | seven 7 12 | eight 8 if true 13 | 14 | body 15 | one 1 16 | two 2 17 | three 3 18 | if true 19 | mixin() 20 | nine 9 -------------------------------------------------------------------------------- /examples/builtins.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/builtins.styl', 'utf8'); 8 | 9 | css.render(str, { filename: 'builtins.styl' }, function(err, css){ 10 | if (err) throw err; 11 | console.log(css); 12 | }); -------------------------------------------------------------------------------- /examples/functions.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/functions.styl', 'utf8'); 8 | 9 | css.render(str, { filename: 'functions.styl' }, function(err, css){ 10 | if (err) throw err; 11 | console.log(css); 12 | }); -------------------------------------------------------------------------------- /examples/variables.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/variables.styl', 'utf8'); 8 | 9 | css.render(str, { filename: 'variables.styl' }, function(err, css){ 10 | if (err) throw err; 11 | console.log(css); 12 | }); -------------------------------------------------------------------------------- /examples/arithmetic.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/arithmetic.styl', 'utf8'); 8 | 9 | css.render(str, { filename: 'arithmetic.styl' }, function(err, css){ 10 | if (err) throw err; 11 | console.log(css); 12 | }); -------------------------------------------------------------------------------- /examples/conversions.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/conversions.styl', 'utf8'); 8 | 9 | css.render(str, { filename: 'conversions.styl' }, function(err, css){ 10 | if (err) throw err; 11 | console.log(css); 12 | }); -------------------------------------------------------------------------------- /examples/import.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/import.styl', 'utf8'); 8 | 9 | css.render(str, { filename: __dirname + '/import.styl' }, function(err, css){ 10 | if (err) throw err; 11 | console.log(css); 12 | }); -------------------------------------------------------------------------------- /test/cases/css.if.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | if true { 4 | color: white; 5 | } 6 | unless (false) { 7 | color: white; 8 | } 9 | 10 | mixin(pad, margin) { 11 | if (pad) { 12 | padding: 5px; 13 | } 14 | if (margin) { 15 | margin: 5px; 16 | } 17 | } 18 | 19 | body 20 | mixin(true, true) 21 | 22 | -------------------------------------------------------------------------------- /test/cases/mixin.conditional.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 20px; 3 | padding: 10px; 4 | padding: 3px; 5 | } 6 | form input { 7 | foo: bar; 8 | bar: baz; 9 | } 10 | form input .two { 11 | level: two; 12 | } 13 | form input .two:hover { 14 | level: three; 15 | } 16 | body { 17 | foo: bar; 18 | bar: baz; 19 | } -------------------------------------------------------------------------------- /examples/compress.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/basic.styl', 'utf8'); 8 | 9 | css.render(str, { filename: 'basic.styl', compress: true }, function(err, css){ 10 | if (err) throw err; 11 | console.log(css); 12 | }); -------------------------------------------------------------------------------- /examples/gradients.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , path = __dirname + '/gradients.styl' 8 | , str = require('fs').readFileSync(path, 'utf8'); 9 | 10 | css.render(str, { filename: path }, function(err, css){ 11 | if (err) throw err; 12 | console.log(css); 13 | }); -------------------------------------------------------------------------------- /test/cases/regression.107.lookup-failure.styl: -------------------------------------------------------------------------------- 1 | minimal-button(bg = #e3e3e3) 2 | background bg 3 | &:hover 4 | background darken(bg, 3) 5 | &:active 6 | background darken(bg, 5) 7 | nested 8 | really-nested 9 | with-even-more-nesting 10 | background bg 11 | 12 | button 13 | minimal-button() -------------------------------------------------------------------------------- /test/cases/regression.252.styl: -------------------------------------------------------------------------------- 1 | 2 | vendors = webkit 3 | 4 | $border-radius = 25px 5 | 6 | @keyframes movingBorder 7 | from 8 | $local-border-radius = 35px 9 | border-radius: 0 0 0 $local-border-radius 10 | 50% 11 | border-radius: 0 0 $border-radius 0 12 | to 13 | border-radius: 0 $border-radius 0 0 14 | -------------------------------------------------------------------------------- /docs/literal.md: -------------------------------------------------------------------------------- 1 | ## Literal CSS 2 | 3 | If for any reason Stylus cannot accommodate a specific need, you can always resort to literal css via `@css`: 4 | 5 | 6 | @css { 7 | body { 8 | font: 14px; 9 | } 10 | } 11 | 12 | compiling to: 13 | 14 | body { 15 | font: 14px; 16 | } -------------------------------------------------------------------------------- /test/cases/for.function.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 10; 3 | foo: 20; 4 | foo: 10; 5 | } 6 | body { 7 | foo: "foo bar baz"; 8 | foo: "foo, bar, baz"; 9 | foo: "1 2 3"; 10 | foo: "1, 2, 3"; 11 | } 12 | body { 13 | foo: 0 Impact; 14 | foo: 1 Arial; 15 | foo: 2 sans-serif; 16 | } 17 | body { 18 | foo: 24; 19 | foo: 30; 20 | } -------------------------------------------------------------------------------- /test/cases/if.else.styl: -------------------------------------------------------------------------------- 1 | 2 | naive-type(val = null) 3 | if val is a 'unit' 4 | unit 5 | else if val is a 'color' 6 | color 7 | else if val is a 'string' 8 | string 9 | else 10 | unknown 11 | 12 | body 13 | foo naive-type('test') 14 | foo naive-type(12) 15 | foo naive-type(#fff) 16 | foo naive-type() 17 | -------------------------------------------------------------------------------- /test/cases/variables.styl: -------------------------------------------------------------------------------- 1 | 2 | size = 14px 3 | font-family = 'Lucida Grande', Arial, sans-serif 4 | $type = solid 5 | blue = #00c 6 | 7 | body 8 | color blue(blue) 9 | 10 | body 11 | font size font-family 12 | padding pad = 5px 13 | margin pad 14 | 15 | a 16 | font 11px Impact, font-family, serif 17 | border 1px $type #fff -------------------------------------------------------------------------------- /examples/implicit-functions.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , str = require('fs').readFileSync(__dirname + '/implicit-functions.styl', 'utf8'); 8 | 9 | css.render(str, { filename: 'implicit-functions.styl' }, function(err, css){ 10 | if (err) throw err; 11 | console.log(css); 12 | }); -------------------------------------------------------------------------------- /test/cases/literal.styl: -------------------------------------------------------------------------------- 1 | @css { 2 | body { 3 | font: 14px; 4 | } 5 | 6 | a { text-decoration: none; } 7 | } 8 | 9 | 10 | border-radius() { 11 | border-radius: arguments[2]; 12 | border-radius: arguments[2] == '/'; 13 | border-radius: '/' == arguments[2]; 14 | } 15 | 16 | #login { 17 | border-radius: 1px 2px / 3px 4px; 18 | } -------------------------------------------------------------------------------- /test/cases/arithmetic.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 12px; 3 | } 4 | h1 { 5 | font-size: 36px; 6 | } 7 | h2 { 8 | font-size: 24px; 9 | font: 2px; 10 | font: 0px; 11 | font: 16px; 12 | } 13 | body { 14 | foo: 100%; 15 | foo: 100%; 16 | foo: 75%; 17 | foo: 25%; 18 | foo: 25%; 19 | } 20 | body { 21 | foo: 10em; 22 | foo: 10em; 23 | } -------------------------------------------------------------------------------- /test/cases/regression.212.styl: -------------------------------------------------------------------------------- 1 | 2 | bold-button(bg = #333, glow = false, intensity = 1) 3 | intensity: intensity 4 | background: bg 5 | glow: glow 6 | 7 | button 8 | bold-button(glow: 'glow', #eee) 9 | 10 | button 11 | bold-button(intensity: 0.5, glow: 'glow') 12 | 13 | button 14 | bold-button(intensity: 0.5, glow: 'glow', black) 15 | -------------------------------------------------------------------------------- /test/cases/arithmetic.unary.styl: -------------------------------------------------------------------------------- 1 | 2 | h1#logo 3 | margin-top - - - 15px 4 | margin-left ~ - 4px 5 | foo !true 6 | foo !!0 7 | foo !-1 8 | foo !99 9 | foo !((99)) 10 | foo not not 0 11 | foo 0px -2px -3px 12 | foo -2px --3px 13 | 14 | body 15 | text-indent -99999px 16 | background #fff url('/some/image.png') no-repeat -29px 1px 17 | -------------------------------------------------------------------------------- /test/cases/bifs.s.styl: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | foo: s('bar()'); 4 | foo: s('bar(%s)', 'baz'); 5 | foo: s('bar(%s)', baz); 6 | foo: s('bar(%s)', 15px); 7 | foo: s('rgba(%s, %s, %s, 0.5)', 255, 100, 50); 8 | foo: s('bar(%Z)', 15px); 9 | foo: s('bar(%s, %s)', 15px); 10 | foo: s('bar(%s, %s)', foo bar, 1 2 3); 11 | foo: s('bar(%s)', hsl(#eee)); 12 | } -------------------------------------------------------------------------------- /test/cases/bifs.type.styl: -------------------------------------------------------------------------------- 1 | body 2 | border-type = solid 3 | size = 15px 4 | background type('test') 5 | background type(12px) 6 | background type(12) 7 | background type(hsl(100deg, 50%, 50%)) 8 | background type(#fff) 9 | background type(something) 10 | background type(size) 11 | background type(type) 12 | background type(border-type) -------------------------------------------------------------------------------- /test/cases/bifs.image-size.styl: -------------------------------------------------------------------------------- 1 | 2 | width(img) 3 | return image-size(img)[0] 4 | 5 | height(img) 6 | return image-size(img)[1] 7 | 8 | body 9 | foo image-size('gif') 10 | foo image-size('gif')[0] == width('gif') 11 | foo image-size('gif')[1] == height('gif') 12 | 13 | body 14 | foo image-size('tux.png') 15 | foo image-size('tux.png') 16 | 17 | -------------------------------------------------------------------------------- /test/cases/mixins.nested.selectors.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 5px; 3 | color: "bar"; 4 | } 5 | body .foo { 6 | color: "bar"; 7 | } 8 | body .foo .bar { 9 | color: "bar"; 10 | } 11 | body { 12 | one: 1; 13 | two: 2; 14 | three: 3; 15 | } 16 | body with some nesting { 17 | four: 4; 18 | } 19 | body with some nesting even more { 20 | five: 5; 21 | } -------------------------------------------------------------------------------- /test/cases/arithmetic.unary.css: -------------------------------------------------------------------------------- 1 | h1#logo { 2 | margin-top: -15px; 3 | margin-left: 3px; 4 | foo: false; 5 | foo: false; 6 | foo: false; 7 | foo: false; 8 | foo: false; 9 | foo: false; 10 | foo: 0px -2px -3px; 11 | foo: 1px; 12 | } 13 | body { 14 | text-indent: -99999px; 15 | background: #fff url("/some/image.png") no-repeat -29px 1px; 16 | } -------------------------------------------------------------------------------- /test/cases/bifs.length.styl: -------------------------------------------------------------------------------- 1 | args(n = null) 2 | length(n) 3 | 4 | vargs(args...) 5 | length(args) 6 | 7 | arguments() 8 | length(arguments) 9 | 10 | body 11 | foo length() 12 | foo length(args()) 13 | foo length(1) 14 | foo length((1 2) (3 4)) 15 | foo length(1 2 3) 16 | foo vargs(1, 2, 3, 4) 17 | foo args(1 2 3 4 5) 18 | foo arguments(1,2,3,4,5,6) -------------------------------------------------------------------------------- /test/cases/bifs.lighten.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | foo: lighten(#000, 50) 4 | foo: lighten(lighten(#000, 50), 50) 5 | 6 | body 7 | foo: lighten(#000, 50%) 8 | foo: lighten(lighten(#000, 50%), 50%) 9 | 10 | body 11 | foo: lighten(#2c2c2c, 50) 12 | foo: lighten(lighten(#2c2c2c, 20), 50) 13 | foo: lighten(lighten(#2c2c2c, 20%), 50%) 14 | foo: lighten(#2c2c2c, 80%) -------------------------------------------------------------------------------- /test/cases/css.mixins.root.wonky.styl: -------------------------------------------------------------------------------- 1 | 2 | hover() 3 | &:hover { color: white; background: black; 4 | em { 5 | color: gray; 6 | } 7 | } 8 | &:active { color: black; background: white; } 9 | 10 | 11 | button(pad) 12 | button, 13 | a.button, 14 | input[type=submit], 15 | input[type=button] { padding: pad; hover(); } 16 | 17 | button(5px 10px); -------------------------------------------------------------------------------- /test/cases/regression.272.styl: -------------------------------------------------------------------------------- 1 | 2 | op(a, b=a, operator='+') 3 | arguments 4 | 5 | body 6 | foo: op(1) // 1 1 + 7 | foo: op(1, 5) // 1 5 + 8 | foo: op(1, 5, '-') // 1 5 - 9 | 10 | op(a, rest...) 11 | arguments 12 | 13 | body 14 | foo: op(1) // 1 15 | foo: op(1, 2) // 1 2 16 | foo: op(1, 2, 3) // 1 2 4 17 | foo: op(1, 2, 3, 4 5 6) // 1 2 3 4 5 6 18 | -------------------------------------------------------------------------------- /editors/Stylus.tmbundle/info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Stylus 7 | uuid 8 | DD7889E4-2ACA-4DF5-838F-FC9D7AEAF3F1 9 | 10 | 11 | -------------------------------------------------------------------------------- /test/cases/bifs.push.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 1 2 3 4 5; 3 | foo: 1; 4 | foo: 5; 5 | } 6 | body { 7 | foo: 5; 8 | foo: 1; 9 | foo: 5; 10 | } 11 | body { 12 | foo: 3; 13 | foo: 1 2 3; 14 | } 15 | body { 16 | foo: 3; 17 | foo: 6; 18 | foo: foo bar baz foo bar baz; 19 | } 20 | body { 21 | foo: one 1 two 2 three 3; 22 | } 23 | body { 24 | foo: 1 2 3 4 5; 25 | } -------------------------------------------------------------------------------- /test/cases/if.selectors.styl: -------------------------------------------------------------------------------- 1 | 2 | if false 3 | something 4 | with a-prop 5 | 6 | if true 7 | form 8 | input 9 | border 1px solid #eee 10 | 11 | [type='text'] 12 | margin 0 13 | 14 | input[type='text'] 15 | display none 16 | 17 | input[type='password'], select 18 | background #eee 19 | 20 | if true 21 | body 22 | font 12px -------------------------------------------------------------------------------- /test/cases/operators.subscript.assign.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: foo 2 "test"; 3 | foo: foo; 4 | foo: 2; 5 | foo: true; 6 | foo: true; 7 | foo: true; 8 | foo: 5; 9 | } 10 | body { 11 | foo: foo "one" "one" "one"; 12 | } 13 | body { 14 | foo: 1 "two" "two"; 15 | } 16 | body { 17 | foo: 1 2 asdf "three"; 18 | } 19 | body { 20 | foo: 1 2 asdf "three"; 21 | } -------------------------------------------------------------------------------- /docs/media.md: -------------------------------------------------------------------------------- 1 | 2 | ## @media 3 | 4 | The `@media` works just as it does within regular css, however with Stylus block notation: 5 | 6 | @media print 7 | #header 8 | #footer 9 | display none 10 | 11 | yielding: 12 | 13 | @media print { 14 | #header, 15 | #footer { 16 | display: none; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/images.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | background url("http://foo.com/bar.png") 4 | 5 | #wrapper 6 | background url(/images/gopher.jpg) 7 | 8 | #footer 9 | background url(/images/gradient.svg) 10 | 11 | .sprite 12 | // both work due to the additional paths option 13 | // passed to stylus.url() 14 | background url(/images/sprite.gif) 15 | background url(sprite.gif) 16 | -------------------------------------------------------------------------------- /test/cases/regression.360.css: -------------------------------------------------------------------------------- 1 | .clearfix:after { 2 | content: "."; 3 | display: block; 4 | height: 0; 5 | clear: both; 6 | visibility: hidden; 7 | } 8 | .clearfix { 9 | display: inline-block; 10 | } 11 | /* Hide from IE Mac \*/ 12 | .clearfix { 13 | display: block; 14 | } 15 | /* End hide from IE Mac */ 16 | .none { 17 | display: none; 18 | } 19 | /* End Clearfix */ -------------------------------------------------------------------------------- /examples/images/gradient.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/cases/comments.styl: -------------------------------------------------------------------------------- 1 | 2 | // foo = 'bar' 3 | 4 | body 5 | color red 6 | // lots of stuff 7 | // wahoo 8 | 9 | // super cool 10 | 11 | // background green 12 | 13 | form 14 | background white 15 | 16 | /* 17 | 18 | body 19 | a 20 | color blue 21 | 22 | */ 23 | // rawr 24 | 25 | html>/**/body select 26 | x:-moz-any-link 27 | x:default select 28 | font-weight bold !important -------------------------------------------------------------------------------- /test/cases/keyframes.fabrication.defaults.css: -------------------------------------------------------------------------------- 1 | @-moz-keyframes foo { 2 | 0% { 3 | color: #000; 4 | } 5 | 6 | 100% { 7 | color: #fff; 8 | } 9 | } 10 | @-webkit-keyframes foo { 11 | 0% { 12 | color: #000; 13 | } 14 | 15 | 100% { 16 | color: #fff; 17 | } 18 | } 19 | @keyframes foo { 20 | 0% { 21 | color: #000; 22 | } 23 | 24 | 100% { 25 | color: #fff; 26 | } 27 | } -------------------------------------------------------------------------------- /test/cases/regression.274.styl: -------------------------------------------------------------------------------- 1 | 2 | color = hsla(0,0,0,0) 3 | 4 | body 5 | foo: color is a 'color' 6 | foo: color == color 7 | foo: color != color 8 | foo: color >= color 9 | foo: color <= color 10 | foo: color > color 11 | foo: color < color 12 | foo: color and 'ok' 13 | foo: color ? 'ok' : 'nope' 14 | foo: !! color 15 | foo: color in (foo bar baz) 16 | foo: color in (foo color baz) -------------------------------------------------------------------------------- /test/cases/vargs.call.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 5px; 3 | padding: 5px 10px; 4 | } 5 | body { 6 | padding: 5px ; 7 | padding: 5px 10px; 8 | } 9 | body { 10 | padding: 5px; 11 | padding: 5px 10px; 12 | padding: 5px 10px 0 2px; 13 | } 14 | body { 15 | test-y: 1px; 16 | test-y: 1px; 17 | padding: 2px 3px; 18 | } 19 | body { 20 | test-y: 1px; 21 | test-x: ; 22 | test-y: 1px; 23 | test-x: 2px; 24 | } -------------------------------------------------------------------------------- /test/cases/bifs.url.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: url("/images/foo.png"); 3 | background: url("/images/foo.png"); 4 | background: url("/images/foo.png"); 5 | background: url("/images/foo.png"); 6 | background: url("/images/foo.png"); 7 | background: url("/images/foo.png"); 8 | background: url("/images/foo.png"); 9 | background: url("/images/foo.png"); 10 | background: url("http://foo.com/images/bar.png"); 11 | } -------------------------------------------------------------------------------- /test/cases/functions.multiple-calls.styl: -------------------------------------------------------------------------------- 1 | 2 | pad(y = 100px) 3 | padding unit(y, 'px') 4 | 5 | body 6 | pad(5px) 7 | pad() 8 | pad(10px) 9 | pad(1) 10 | pad() 11 | 12 | pad-x(n) 13 | n = unit(n, 'px') 14 | padding-left n 15 | padding-right n 16 | 17 | pad-y(y) 18 | padding-top n = unit(y, 'px') 19 | padding-bottom n 20 | 21 | pad(x, y) 22 | pad-x(x) 23 | pad-y(y) 24 | 25 | form 26 | pad(5, 10) -------------------------------------------------------------------------------- /test/cases/functions.variable.styl: -------------------------------------------------------------------------------- 1 | 2 | add(a, b) 3 | a + b 4 | 5 | size-function = add 6 | 7 | size(n) 8 | size-function(n, n) 9 | 10 | padding-x(n) 11 | padding-left n 12 | padding-right n 13 | 14 | padding-y(n) 15 | padding-top n 16 | padding-bottom n 17 | 18 | mixin(name, n) 19 | name(n) 20 | 21 | body 22 | fn = padding-x 23 | font size(14px) 24 | fn(5px) 25 | 26 | form 27 | mixin(padding-y, 10px) -------------------------------------------------------------------------------- /test/cases/operators.assignment.function.styl: -------------------------------------------------------------------------------- 1 | 2 | test(n) 3 | n += 5 4 | n += 5 5 | 6 | body 7 | foo test(10) 8 | 9 | test(n) 10 | n -= 2 11 | n -= 3 12 | 13 | body 14 | foo test(10) 15 | 16 | test(n) 17 | n *= 2 18 | n *= 2 19 | 20 | body 21 | foo test(5) 22 | 23 | test(n) 24 | n /= 2 25 | n /= 4 26 | 27 | body 28 | foo test(20) 29 | 30 | test(n) 31 | n %= 2 32 | 33 | body 34 | foo test(5) -------------------------------------------------------------------------------- /test/cases/bifs.url.styl: -------------------------------------------------------------------------------- 1 | body 2 | background url("/images/foo.png") 3 | background url(/images/foo.png) 4 | 5 | dir = '/images' 6 | img = 'foo.png' 7 | background url(dir/foo.png) 8 | background url(dir/img) 9 | 10 | background url('/images/' + img) 11 | background url(dir'/foo.png') 12 | background url(dir + '/foo.png') 13 | background url(dir + '/' + img) 14 | 15 | background url(http://foo.com/images/bar.png) -------------------------------------------------------------------------------- /test/cases/css.mixins.root.styl: -------------------------------------------------------------------------------- 1 | 2 | hover() 3 | &:hover { 4 | color: white; 5 | background: black; 6 | em { 7 | color: gray; 8 | } 9 | } 10 | &:active { 11 | color: black; 12 | background: white; 13 | } 14 | 15 | 16 | button(pad) 17 | button, 18 | a.button, 19 | input[type=submit], 20 | input[type=button] { 21 | padding: pad; 22 | hover(); 23 | } 24 | 25 | button(5px 10px); -------------------------------------------------------------------------------- /test/cases/hack.star.css: -------------------------------------------------------------------------------- 1 | html>body p code { 2 | *white-space: normal; 3 | } 4 | body { 5 | *white-space: normal; 6 | } 7 | body { 8 | *white-space: normal; 9 | } 10 | body { 11 | *white-space: normal; 12 | } 13 | * foo { 14 | display: none; 15 | } 16 | body * { 17 | display: none; 18 | } 19 | body { 20 | *white-space: normal; 21 | } 22 | body * foo { 23 | bar: baz; 24 | } 25 | body * foo { 26 | display: none; 27 | } -------------------------------------------------------------------------------- /test/cases/if.mixin.styl: -------------------------------------------------------------------------------- 1 | 2 | test(n) 3 | if n < 0 4 | got below 5 | else 6 | got above 7 | 8 | test-nested(a, b) 9 | if a > 1 10 | if unit(-5) == '' 11 | got empty 12 | yup just lots of empty 13 | else 14 | got unit(-5px) 15 | 16 | test-unless(n = 0) 17 | unless n 18 | padding 10px 19 | 20 | body 21 | test(5px) 22 | test(-5px) 23 | test-nested(5px, -5) 24 | test-unless() 25 | -------------------------------------------------------------------------------- /test/cases/operators.equality.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: true; 3 | foo: true; 4 | foo: true; 5 | foo: true; 6 | foo: true; 7 | foo: true; 8 | foo: true; 9 | foo: true; 10 | } 11 | body { 12 | foo: true; 13 | foo: true; 14 | foo: true; 15 | } 16 | body { 17 | foo: true; 18 | foo: true; 19 | foo: true; 20 | } 21 | body { 22 | foo: true; 23 | foo: true; 24 | } 25 | body { 26 | foo: true; 27 | foo: true; 28 | } -------------------------------------------------------------------------------- /test/cases/operator.range.styl: -------------------------------------------------------------------------------- 1 | body 2 | small = 1..5 3 | large = (1..5) (6..10) 4 | 5 | foo small 6 | foo large 7 | 8 | foo small[0] 9 | foo large[0] 10 | 11 | foo length(small) 12 | foo length(large) 13 | 14 | foo small[length(small) - 1] 15 | foo large[length(large) - 1] 16 | 17 | foo small[-1] == null 18 | foo small[123123] == null 19 | 20 | body 21 | start = 1 22 | end = 3 23 | foo start..end -------------------------------------------------------------------------------- /test/cases/selectors.pseudo.styl: -------------------------------------------------------------------------------- 1 | 2 | mixin() 3 | td:nth-of-type(2) 4 | td:nth-of-type(3) 5 | background black 6 | 7 | ul 8 | mixin() 9 | 10 | table 11 | td:nth-child(2) 12 | td:nth-child(3) 13 | td:nth-child(4) 14 | td:nth-child(5) 15 | td:first-letter 16 | background black 17 | li:first-child 18 | li:last-child 19 | background white 20 | 21 | table 22 | :nth-child(2) 23 | :nth-child(3) 24 | background black -------------------------------------------------------------------------------- /test/cases/operators.assignment.root.styl: -------------------------------------------------------------------------------- 1 | 2 | 3 | n = 10 4 | a = n = n + 10 5 | a += 1 6 | 7 | body 8 | foo n 9 | foo a 10 | 11 | n = 10 12 | n += 5 13 | n += 5 14 | 15 | body 16 | foo n 17 | 18 | n = 10 19 | n -= 2 20 | n -= 3 21 | 22 | body 23 | foo n 24 | 25 | n = 5 26 | n *= 2 27 | n *= 2 28 | 29 | body 30 | foo n 31 | 32 | n = 20 33 | n /= 2 34 | n /= 4 35 | 36 | body 37 | foo n 38 | 39 | n = 5 40 | n %= 2 41 | 42 | body 43 | foo n -------------------------------------------------------------------------------- /test/cases/functions.defaults.styl: -------------------------------------------------------------------------------- 1 | 2 | size = 15px 3 | small = 5 4 | 5 | pad-var(x, y = size) 6 | padding y x y x 7 | 8 | pad-arg(x, y = x) 9 | padding y x y x 10 | 11 | body 12 | pad-var(5px) 13 | 14 | a.button 15 | pad-arg(10px) 16 | 17 | a.button-2 18 | pad-arg(10px, 2px) 19 | 20 | add(a, b) 21 | a + b 22 | 23 | pad-call(n = unit(add(small, small), 'px')) 24 | padding n 25 | 26 | body 27 | pad-call() 28 | 29 | .button 30 | pad-call(5px) -------------------------------------------------------------------------------- /test/cases/mixins.nested.selectors.styl: -------------------------------------------------------------------------------- 1 | 2 | mixin(n) 3 | padding n 4 | var = 'bar' 5 | color var 6 | .foo 7 | color var 8 | .bar 9 | color var 10 | 11 | body 12 | foo = 'foo' 13 | mixin(5px) 14 | 15 | three(n) 16 | three n 17 | with some nesting 18 | four n = n + 1 19 | even more 20 | five n + 1 21 | 22 | two(n) 23 | two n 24 | three(n + 1) 25 | 26 | one(n) 27 | one n 28 | two(n + 1) 29 | 30 | body 31 | one(1) -------------------------------------------------------------------------------- /test/cases/operators.assignment.mixin.styl: -------------------------------------------------------------------------------- 1 | 2 | test(n) 3 | n += 5 4 | n += 5 5 | foo n 6 | 7 | body 8 | test(10) 9 | 10 | test(n) 11 | n -= 2 12 | n -= 3 13 | foo n 14 | 15 | body 16 | test(10) 17 | 18 | test(n) 19 | n *= 2 20 | n *= 2 21 | foo n 22 | 23 | body 24 | test(5) 25 | 26 | test(n) 27 | n /= 2 28 | n /= 4 29 | foo n 30 | 31 | body 32 | test(20) 33 | 34 | test(n) 35 | n %= 2 36 | foo n 37 | 38 | body 39 | test(5) -------------------------------------------------------------------------------- /test/cases/arithmetic.styl: -------------------------------------------------------------------------------- 1 | 2 | size = 12px 3 | large = size * (3 - 1) 4 | huge = size * 3 5 | 6 | body 7 | font-size size 8 | 9 | h1 10 | font-size huge 11 | 12 | h2 13 | font-size large 14 | font 5px % 3 15 | font 5px % 5 16 | font 2px ** 4 17 | y = 10 18 | x = 15 19 | 20 | body { 21 | foo: 50% * 2; 22 | foo: 2 * 50%; 23 | foo: 50 + 50%; 24 | foo: 50 - 50%; 25 | foo: 50% - 50%; 26 | } 27 | body { 28 | foo: 5 + 5em; 29 | foo: 5em + 5; 30 | } -------------------------------------------------------------------------------- /test/cases/operators.mixins.styl: -------------------------------------------------------------------------------- 1 | 2 | stringish(val = false) 3 | 'string' == type(val) or 'ident' == type(val) 4 | 5 | string(val) 6 | '' + val 7 | 8 | body 9 | // false 10 | foo stringish(12) 11 | 12 | // true 13 | foo stringish('12') 14 | 15 | // true 16 | foo stringish(wahoo) 17 | 18 | // false 19 | num = 12 20 | foo stringish(num) 21 | foo stringish() 22 | 23 | foo string(something) 24 | foo string('something') 25 | foo string(12) -------------------------------------------------------------------------------- /test/cases/regression.146.css: -------------------------------------------------------------------------------- 1 | input[for=name] { 2 | width: 200px; 3 | } 4 | body { 5 | foo: 1; 6 | } 7 | body { 8 | foo: 2; 9 | } 10 | body { 11 | foo: 3; 12 | } 13 | body foo { 14 | bar: 1; 15 | bar: 2; 16 | bar: 3; 17 | } 18 | #login foo, 19 | #login input[for=name] { 20 | foo: bar; 21 | } 22 | #login foo input[for=name] { 23 | bar: 1; 24 | } 25 | #login foo input[for=name] { 26 | bar: 2; 27 | } 28 | #login foo input[for=name] { 29 | bar: 3; 30 | } -------------------------------------------------------------------------------- /test/cases/selectors.nested.styl: -------------------------------------------------------------------------------- 1 | 2 | form 3 | .foo 4 | color black 5 | .bar 6 | padding 5px 7 | color red 8 | 9 | body 10 | .foo 11 | .bar 12 | display none 13 | 14 | body 15 | .foo 16 | .bar 17 | .baz 18 | .sdf 19 | display none 20 | 21 | .foo 22 | .bar 23 | .baz 24 | .raz 25 | something 'else' 26 | 27 | .foo 28 | .bar 29 | .baz 30 | .raz 31 | background red 32 | .ASDF 33 | background white -------------------------------------------------------------------------------- /test/cases/regression.146.styl: -------------------------------------------------------------------------------- 1 | input[for=name] 2 | width 200px 3 | 4 | nums = 1 2 3 5 | for n in nums 6 | body 7 | foo n 8 | 9 | body 10 | foo 11 | for n in nums 12 | bar n 13 | 14 | something() 15 | nums = 1 2 3 16 | foo 17 | input[for=name] 18 | foo bar 19 | 20 | #login 21 | something() 22 | 23 | something() 24 | nums = 1 2 3 25 | foo 26 | for n in nums 27 | input[for=name] 28 | bar n 29 | 30 | #login 31 | something() -------------------------------------------------------------------------------- /test/cases/functions.return.each.styl: -------------------------------------------------------------------------------- 1 | 2 | join1(delim, vals) 3 | buf = '' 4 | for val, i in vals 5 | if i 6 | buf += delim + val 7 | else 8 | buf += val 9 | 10 | join2(delim, vals) 11 | buf = '' 12 | for val, i in vals 13 | buf += i ? delim + val : val 14 | 15 | body 16 | foo join1(' ', 1 2 3) 17 | foo join1(', ', 1 2 3) 18 | foo join1(',', 1 2 3) 19 | 20 | body 21 | foo join2(' ', 1 2 3) 22 | foo join2(', ', 1 2 3) 23 | foo join2(',', 1 2 3) -------------------------------------------------------------------------------- /test/cases/selectors.pseudo.elements.styl: -------------------------------------------------------------------------------- 1 | input::selection 2 | input::focus-inner 3 | border: 0 4 | padding: 0 5 | 6 | input::-moz-selection 7 | border: 0 8 | 9 | p 10 | ::selection 11 | background: black 12 | 13 | ::selection 14 | background: black 15 | 16 | p::selection 17 | a::selection 18 | background: black 19 | 20 | p::selection { 21 | color: white; 22 | background: black; 23 | } 24 | 25 | vendors = webkit 26 | 27 | body 28 | ::selection 29 | color: white 30 | -------------------------------------------------------------------------------- /test/cases/vargs.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 5px; 3 | padding: 5px; 4 | } 5 | body { 6 | padding: 5px ; 7 | padding: 5px 10px; 8 | } 9 | body { 10 | padding: 5px; 11 | padding: 5px 10px; 12 | padding: 5px 10px 0 2px; 13 | } 14 | body { 15 | test-y: 1px; 16 | test-y: 1px; 17 | padding: 2px 3px; 18 | } 19 | body { 20 | test-y: 1px; 21 | test-x: ; 22 | test-y: 1px; 23 | test-x: 2px; 24 | } 25 | body { 26 | pad: 1; 27 | pad: 2; 28 | pad: 3 4 5; 29 | len: 3; 30 | } -------------------------------------------------------------------------------- /examples/implicit-functions.styl: -------------------------------------------------------------------------------- 1 | 2 | border-radius() 3 | -webkit-border-radius arguments 4 | -moz-border-radius arguments 5 | border-radius arguments 6 | 7 | form 8 | border-radius 5px 9 | 10 | a.button 11 | border-radius 10px 12 | 13 | 14 | support-for-ie ?= true 15 | 16 | opacity(n) 17 | opacity n 18 | if support-for-ie 19 | filter unquote('progid:DXImageTransform.Microsoft.Alpha(Opacity=' + round(n * 100) + ')') 20 | 21 | #logo 22 | &:hover 23 | opacity 0.5 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | SRC = $(shell find lib -name "*.js") 3 | TM_BUNDLE = editors/Stylus.tmbundle 4 | TM_BUNDLE_DEST = ~/Library/Application\ Support/TextMate/Bundles 5 | 6 | test: test-integration 7 | 8 | test-integration: 9 | @node test/run.js 10 | 11 | install-bundle: 12 | cp -fr $(TM_BUNDLE) $(TM_BUNDLE_DEST) 13 | 14 | update-bundle: 15 | cp -fr $(TM_BUNDLE_DEST)/Stylus.tmbundle editors 16 | 17 | benchmark: 18 | @node bm.js 19 | 20 | .PHONY: test test-integration install-bundle update-bundle benchmark -------------------------------------------------------------------------------- /test/cases/hack.star.styl: -------------------------------------------------------------------------------- 1 | html>body p code {*white-space:normal;} 2 | 3 | body 4 | *white-space normal 5 | 6 | body 7 | *white-space: normal 8 | 9 | mixin() 10 | *white-space: normal 11 | 12 | body 13 | mixin() 14 | 15 | mixin() 16 | *white-space normal 17 | 18 | * foo 19 | display: none 20 | 21 | body 22 | * 23 | display: none 24 | 25 | body 26 | mixin() 27 | 28 | mixin() 29 | * foo 30 | bar: baz 31 | 32 | body 33 | mixin() 34 | 35 | body * foo { 36 | display: none 37 | } -------------------------------------------------------------------------------- /test/cases/css.whitespace.styl: -------------------------------------------------------------------------------- 1 | 2 | body 3 | padding 5px 4 | 5 | body 6 | padding 5px 7 | 8 | body 9 | padding: 5px; margin: 0; 10 | 11 | body 12 | padding: 5px; 13 | margin: 0; 14 | 15 | body { 16 | padding: 5px; 17 | margin: 0; 18 | } 19 | 20 | body { 21 | padding: 5px; margin: 0; 22 | } 23 | 24 | body { 25 | padding: 5px; 26 | } 27 | 28 | ul { 29 | li { 30 | padding: 5px; 31 | } 32 | } 33 | 34 | 35 | body{padding: 5px;} 36 | foo 37 | bar {color:'asdf'} 38 | bar{color:'asdf'} 39 | -------------------------------------------------------------------------------- /test/cases/regression.139.styl: -------------------------------------------------------------------------------- 1 | 2 | opposite-position(pos) { 3 | return bottom if pos == top; 4 | return top if pos == bottom; 5 | return right if pos == left; 6 | return left if pos == right; 7 | error('Invalid position ' + pos) 8 | } 9 | 10 | opposite(positions) { 11 | for pos in positions { 12 | pos = opposite-position(pos); 13 | ret = ret is defined ? ret pos : pos; 14 | } 15 | } 16 | 17 | body { 18 | foo: opposite(top); 19 | foo: opposite(left); 20 | foo: opposite(top left); 21 | } 22 | -------------------------------------------------------------------------------- /test/cases/selectors.complex.styl: -------------------------------------------------------------------------------- 1 | body 2 | form input.hide, 3 | foo bar, 4 | .hidden 5 | &:hover 6 | &:focus 7 | display none 8 | 9 | body 10 | form input, .hidden 11 | display none 12 | 13 | ul 14 | > li 15 | padding 5px 16 | border 1px solid #eee 17 | &:first-child, 18 | &:last-child 19 | border none 20 | &:first-child 21 | padding-top 0 22 | &:last-child 23 | padding-bottom 0 24 | 25 | body 26 | form > input:nth-child(2) 27 | border 1px solid #eee -------------------------------------------------------------------------------- /test/cases/css.whitespace.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 5px; 3 | } 4 | body { 5 | padding: 5px; 6 | } 7 | body { 8 | padding: 5px; 9 | margin: 0; 10 | } 11 | body { 12 | padding: 5px; 13 | margin: 0; 14 | } 15 | body { 16 | padding: 5px; 17 | margin: 0; 18 | } 19 | body { 20 | padding: 5px; 21 | margin: 0; 22 | } 23 | body { 24 | padding: 5px; 25 | } 26 | ul li { 27 | padding: 5px; 28 | } 29 | body { 30 | padding: 5px; 31 | } 32 | foo bar { 33 | color: "asdf"; 34 | } 35 | foo bar { 36 | color: "asdf"; 37 | } -------------------------------------------------------------------------------- /test/cases/for.complex.styl: -------------------------------------------------------------------------------- 1 | vals = a b c d e f g 2 | 3 | body 4 | for val in vals 5 | foo val 6 | 7 | body 8 | for val in vals[0] 9 | foo val 10 | 11 | body 12 | for val, i in vals[1..3] 13 | foo i unquote(':') val 14 | 15 | body 16 | for msg in (error 'test') (error 'foo') 17 | foo msg[0] test msg[1] 18 | 19 | body 20 | for char in a b c d 21 | for num in 0 1 2 3 22 | foo num char 23 | 24 | fonts = helvetica, arial, sans-serif 25 | 26 | body 27 | for font in fonts 28 | foo font 29 | -------------------------------------------------------------------------------- /examples/js-functions.styl: -------------------------------------------------------------------------------- 1 | 2 | image-width(path) 3 | return image-size(path)[0] 4 | 5 | image-height(path) 6 | return image-size(path)[1] 7 | 8 | body 9 | font add(5px, 10px) 10 | font sub(5px, 10px) 11 | 12 | #jesus 13 | width image-width('images/jesus.gif') 14 | height image-height('images/jesus.gif') 15 | 16 | #jesus-2 17 | width image-size('images/jesus.gif')[0] 18 | height image-size('images/jesus.gif')[1] 19 | 20 | #jesus-3 21 | size = image-size('images/jesus.gif') 22 | width size[0] 23 | height size[1] -------------------------------------------------------------------------------- /examples/variables.styl: -------------------------------------------------------------------------------- 1 | 2 | font-families = "Lucida Grande", Arial 3 | main-width = 80% 4 | main-color = #fff 5 | sidebar-width = main-width / 2 6 | 7 | // Mixins can use conditionals 8 | // to supply defaults 9 | unless font-families is defined 10 | font-families = 'WAHOO' 11 | 12 | // Alternatively we may use ?= 13 | font-families ?= 'WAHOO' 14 | 15 | body 16 | size = 12px 17 | font size font-families, sans-serif 18 | color main-color 19 | 20 | #wrapper 21 | width main-width 22 | 23 | .sidebar 24 | width sidebar-width -------------------------------------------------------------------------------- /examples/conversions.styl: -------------------------------------------------------------------------------- 1 | 2 | seconds(n) 3 | 0s + n 4 | 5 | body 6 | foo 15px - 5px 7 | foo 15px - 5 8 | 9 | // 60.8mm 10 | foo 5cm - 2mm 11 | foo 10mm + 2in 12 | 13 | // 3.54cm 14 | foo 1cm + 1in 15 | 16 | // 3in 17 | foo 5in - 5.08cm 18 | 19 | // 0.8s 20 | foo 1s - 200ms 21 | 22 | // 3500ms 23 | foo 1500ms + 2s 24 | 25 | // 3000Hz 26 | foo 1000Hz + 2kHz 27 | 28 | // 1kHz 29 | foo 3kHz - (1000Hz * 2) 30 | 31 | n = 30% 32 | foo unit(n, 'px') 33 | 34 | foo seconds(1500ms) -------------------------------------------------------------------------------- /test/cases/reset.styl: -------------------------------------------------------------------------------- 1 | html, body, div, span, applet, object, iframe, 2 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 3 | a, abbr, acronym, address, big, cite, code, 4 | del, dfn, em, font, img, ins, kbd, q, s, samp, 5 | small, strike, strong, sub, sup, tt, var, 6 | b, u, i, center, 7 | dl, dt, dd, ol, ul, li, 8 | fieldset, form, label, legend, 9 | table, caption, tbody, tfoot, thead, tr, th, td 10 | margin 0 11 | padding 0 12 | border 0 13 | outline 0 14 | font-size 100% 15 | vertical-align baseline 16 | background transparent -------------------------------------------------------------------------------- /examples/middleware.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var connect = require('connect') 7 | , stylus = require('../'); 8 | 9 | // Setup server 10 | // $ curl http://localhost:3000/functions.css 11 | 12 | var server = connect.createServer( 13 | stylus.middleware({ 14 | src: __dirname 15 | , dest: __dirname + '/public' 16 | , compress: true 17 | , debug: true 18 | }), 19 | connect.static(__dirname + '/public') 20 | ); 21 | 22 | server.listen(3000); 23 | console.log('server listening on port 3000'); -------------------------------------------------------------------------------- /test/cases/mixins.complex.fix-to.styl: -------------------------------------------------------------------------------- 1 | 2 | fix-to(a, b) 3 | position fixed 4 | {a} 0 5 | {b} 0 6 | 7 | .button 8 | fix-to bottom left 9 | 10 | 11 | fix-to(pos...) 12 | position fixed 13 | if length(pos) == 2 14 | {pos[0]} 0 15 | {pos[1]} 0 16 | else if length(pos) == 4 17 | a = pos[0..1] 18 | b = pos[2..3] 19 | {a[0]} a[1] 20 | {b[0]} b[1] 21 | else 22 | error('invalid arguments. fix-to: [n] [n];') 23 | 24 | .button 25 | fix-to bottom left 26 | 27 | .button 28 | fix-to bottom 5px left 5px -------------------------------------------------------------------------------- /test/cases/selectors.complex.css: -------------------------------------------------------------------------------- 1 | body form input.hide, 2 | body foo bar, 3 | body .hidden, 4 | body:hover, 5 | body:focus { 6 | display: none; 7 | } 8 | body form input, 9 | body .hidden { 10 | display: none; 11 | } 12 | ul > li { 13 | padding: 5px; 14 | border: 1px solid #eee; 15 | } 16 | ul > li:first-child, 17 | ul > li:last-child { 18 | border: none; 19 | } 20 | ul > li:first-child { 21 | padding-top: 0; 22 | } 23 | ul > li:last-child { 24 | padding-bottom: 0; 25 | } 26 | body form > input:nth-child(2) { 27 | border: 1px solid #eee; 28 | } -------------------------------------------------------------------------------- /test/cases/operators.in.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: true; 3 | foo: true; 4 | foo: false; 5 | } 6 | body { 7 | foo: true; 8 | } 9 | body { 10 | foo: true; 11 | foo: true; 12 | foo: false; 13 | } 14 | body { 15 | foo: false; 16 | foo: true; 17 | foo: true; 18 | foo: true; 19 | foo: false; 20 | } 21 | body { 22 | foo: false; 23 | foo: false; 24 | foo: true; 25 | foo: false; 26 | foo: true; 27 | } 28 | body { 29 | foo: true; 30 | foo: false; 31 | } 32 | body { 33 | foo: true; 34 | foo: false; 35 | foo: true; 36 | foo: true; 37 | } -------------------------------------------------------------------------------- /test/cases/regression.142.css: -------------------------------------------------------------------------------- 1 | foo, 2 | bar, 3 | baz { 4 | display: none; 5 | } 6 | foo, 7 | bar, 8 | baz { 9 | display: none; 10 | } 11 | body :nth-child(2), 12 | body foo bar, 13 | body bar, 14 | body baz { 15 | display: none; 16 | } 17 | body { 18 | foo: bar; 19 | } 20 | body bar, 21 | body baz { 22 | display: none; 23 | } 24 | body foo, 25 | body bar, 26 | body baz { 27 | display: none; 28 | } 29 | body foo, 30 | body :nth-child(2), 31 | body bar { 32 | display: none; 33 | } 34 | body { 35 | foo: bar; 36 | } 37 | body { 38 | foo: 3; 39 | } -------------------------------------------------------------------------------- /docs/escape.md: -------------------------------------------------------------------------------- 1 | 2 | ## Escaping 3 | 4 | Stylus allows you to escape characters, effectively turning them into identifiers, so that they can be rendered as literals. For example: 5 | 6 | body 7 | padding 1 \+ 2 8 | 9 | will compile to: 10 | 11 | body { 12 | padding: 1 + 2; 13 | } 14 | 15 | 16 | Not that Stylus requires that `/` is parenthesized when used in a property: 17 | 18 | body 19 | font 14px/1.4 20 | font (14px/1.4) 21 | 22 | yields: 23 | 24 | body { 25 | font: 14px/1.4; 26 | font: 10px; 27 | } -------------------------------------------------------------------------------- /examples/arithmetic.styl: -------------------------------------------------------------------------------- 1 | 2 | font-families = "Lucida Grande", Arial, sans-serif 3 | font-size = 14px 4 | primary-color = #3a3a3a 5 | width = 800px 6 | pad = 20px 7 | 8 | body 9 | font font-size/1.5 font-families 10 | background white 11 | color primary-color 12 | 13 | h1 14 | font-size font-size * (5 - 3) 15 | color primary-color + #030303 16 | 17 | h2 18 | color primary-color + 20% 19 | 20 | #wrapper 21 | width width 22 | 23 | .side-bar 24 | padding pad 25 | width (width / 3) - pad 26 | // 6 27 | height 3 - - - - 3 28 | // 7 29 | height 1 + 2 * 3 -------------------------------------------------------------------------------- /test/cases/css.mixins.root.css: -------------------------------------------------------------------------------- 1 | button, 2 | a.button, 3 | input[type=submit], 4 | input[type=button] { 5 | padding: 5px 10px; 6 | } 7 | button:hover, 8 | a.button:hover, 9 | input[type=submit]:hover, 10 | input[type=button]:hover { 11 | color: #fff; 12 | background: #000; 13 | } 14 | button:hover em, 15 | a.button:hover em, 16 | input[type=submit]:hover em, 17 | input[type=button]:hover em { 18 | color: #808080; 19 | } 20 | button:active, 21 | a.button:active, 22 | input[type=submit]:active, 23 | input[type=button]:active { 24 | color: #000; 25 | background: #fff; 26 | } -------------------------------------------------------------------------------- /test/cases/css.mixins.root.wonky.css: -------------------------------------------------------------------------------- 1 | button, 2 | a.button, 3 | input[type=submit], 4 | input[type=button] { 5 | padding: 5px 10px; 6 | } 7 | button:hover, 8 | a.button:hover, 9 | input[type=submit]:hover, 10 | input[type=button]:hover { 11 | color: #fff; 12 | background: #000; 13 | } 14 | button:hover em, 15 | a.button:hover em, 16 | input[type=submit]:hover em, 17 | input[type=button]:hover em { 18 | color: #808080; 19 | } 20 | button:active, 21 | a.button:active, 22 | input[type=submit]:active, 23 | input[type=button]:active { 24 | color: #000; 25 | background: #fff; 26 | } -------------------------------------------------------------------------------- /test/cases/mixin.conditional.styl: -------------------------------------------------------------------------------- 1 | 2 | pad(size = small) 3 | if large == size 4 | padding 20px 5 | if medium == size 6 | padding 10px 7 | if small == size 8 | padding 3px 9 | 10 | body 11 | pad(large) 12 | pad(medium) 13 | pad() 14 | pad(invalid) 15 | 16 | nested(val) 17 | if val 18 | foo bar 19 | bar baz 20 | .two 21 | level two 22 | &:hover 23 | level three 24 | 25 | form input 26 | nested(true) 27 | nested(false) 28 | 29 | break() 30 | foo bar 31 | bar baz 32 | return 33 | baz raz 34 | 35 | body 36 | break() -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { "name": "stylus" 2 | , "description": "Robust, expressive, and feature-rich CSS superset" 3 | , "version": "0.15.1" 4 | , "author": "TJ Holowaychuk " 5 | , "keywords": ["css", "parser", "style", "stylesheets", "jade", "language"] 6 | , "repository": "git://github.com/learnboost/stylus" 7 | , "main": "./index.js" 8 | , "engines": { "node": ">= 0.2.4" } 9 | , "bin": { "stylus": "./bin/stylus" } 10 | , "scripts" : { "prepublish" : "npm prune" } 11 | , "dependencies": { 12 | "cssom": "0.2.0" 13 | , "growl": "1.1.0" 14 | } 15 | } -------------------------------------------------------------------------------- /docs/font-face.md: -------------------------------------------------------------------------------- 1 | 2 | ## @font-face 3 | 4 | The `@font-face` at-rule expects as you would expect, simply followed by a block of properties: 5 | 6 | 7 | @font-face 8 | font-family Geo 9 | font-style normal 10 | src url(fonts/geo_sans_light/GensansLight.ttf) 11 | 12 | .ingeo 13 | font-family Geo 14 | 15 | yielding: 16 | 17 | 18 | @font-face { 19 | font-family: Geo; 20 | font-style: normal; 21 | src: url("fonts/geo_sans_light/GensansLight.ttf"); 22 | } 23 | .ingeo { 24 | font-family: Geo; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /lib/nodes/import.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Import 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node'); 13 | 14 | /** 15 | * Initialize a new `Import` with the given `expr`. 16 | * 17 | * @param {Expression} expr 18 | * @api public 19 | */ 20 | 21 | var Import = module.exports = function Import(expr){ 22 | Node.call(this); 23 | this.path = expr; 24 | }; 25 | 26 | /** 27 | * Inherit from `Node.prototype`. 28 | */ 29 | 30 | Import.prototype.__proto__ = Node.prototype; 31 | -------------------------------------------------------------------------------- /test/cases/functions.nested.styl: -------------------------------------------------------------------------------- 1 | 2 | add(a, b) 3 | div(a, b) 4 | a / b 5 | a + div(b, 2) 6 | 7 | body 8 | padding add(1,5) 9 | // => 3.5 10 | 11 | add(a, b) 12 | half() 13 | b / 2 14 | a + half() 15 | 16 | body 17 | padding add(1,5) 18 | // => 3.5 19 | 20 | getFunction(name) 21 | if name == 'add' 22 | add(a, b) 23 | a + b 24 | else 25 | sub(a, b) 26 | a - b 27 | 28 | body 29 | fn = getFunction('add') 30 | padding fn(5, 5) 31 | // => 10 32 | 33 | fn = getFunction('sub') 34 | fn2 = fn 35 | fn3 = fn2 36 | padding fn3(5, 5) 37 | // => 0 -------------------------------------------------------------------------------- /test/cases/selectors.nested.css: -------------------------------------------------------------------------------- 1 | form .foo { 2 | color: #000; 3 | } 4 | form .foo .bar { 5 | padding: 5px; 6 | color: #f00; 7 | } 8 | body .foo .bar { 9 | display: none; 10 | } 11 | body .foo .baz, 12 | body .bar .baz, 13 | body .foo .sdf, 14 | body .bar .sdf { 15 | display: none; 16 | } 17 | .foo .baz, 18 | .bar .baz, 19 | .foo .raz, 20 | .bar .raz { 21 | something: "else"; 22 | } 23 | .foo .baz, 24 | .bar .baz, 25 | .foo .raz, 26 | .bar .raz { 27 | background: #f00; 28 | } 29 | .foo .baz .ASDF, 30 | .bar .baz .ASDF, 31 | .foo .raz .ASDF, 32 | .bar .raz .ASDF { 33 | background: #fff; 34 | } -------------------------------------------------------------------------------- /test/cases/arithmetic.color.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: #ce4e4e; 3 | foo: #ce4e4e; 4 | } 5 | body { 6 | foo: #ba3a3a; 7 | foo: #ba3a3a; 8 | } 9 | body { 10 | foo: #d16c6c; 11 | foo: #d16c6c; 12 | } 13 | body { 14 | foo: #a13333; 15 | foo: #a13333; 16 | } 17 | body { 18 | foo: #c46f44; 19 | foo: #c46f44; 20 | } 21 | body { 22 | foo: #c4446f; 23 | foo: #c4446f; 24 | } 25 | body { 26 | foo: #c476a8; 27 | foo: #c476a8; 28 | } 29 | body { 30 | foo: #c476a8; 31 | foo: #c41200; 32 | } 33 | body { 34 | foo: #ed834e; 35 | foo: #ed834e; 36 | } 37 | body { 38 | foo: #825363; 39 | foo: #825363; 40 | } -------------------------------------------------------------------------------- /examples/functions.styl: -------------------------------------------------------------------------------- 1 | 2 | 3 | // ?= would allow us to define the images global before @importing 4 | // the file if we were to distribute this 5 | 6 | images ?= '/images' 7 | 8 | image(path) 9 | url(join('/', images path)) 10 | 11 | // or 12 | 13 | image(path) 14 | url(images + '/' + path) 15 | 16 | body 17 | background image('foo.png') 18 | 19 | // functions can act as both mixins 20 | // or have a return value 21 | 22 | image(path) 23 | if mixin 24 | background image(path) 25 | else 26 | url(images + '/' + path) 27 | 28 | body 29 | image('something.png') 30 | background image('something.png') -------------------------------------------------------------------------------- /bm.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var stylus = require('./'); 7 | 8 | var times = 200 9 | , n = times 10 | , start = new Date; 11 | 12 | console.log('compiling %d times', times); 13 | 14 | while (n--) { 15 | stylus('body\n color: white;\n background: url(/images/foo.png)\n a\n &:hover\n text-decoration: underline;') 16 | .render(function(err, css){}); 17 | } 18 | 19 | var duration = new Date - start; 20 | console.log(' duration: %dms', duration); 21 | console.log(' average: %dms', duration / times); 22 | console.log(' per second: %d', (times / (duration / 1000)).toFixed(1)); 23 | -------------------------------------------------------------------------------- /examples/images.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var stylus = require('../') 7 | , nodes = stylus.nodes 8 | , path = __dirname + '/images.styl' 9 | , str = require('fs').readFileSync(path, 'utf8'); 10 | 11 | // the paths option is merged with the general options 12 | // so it is completely optional, however this now allows us to use 13 | // url(sprite.gif) instead of url(images/sprite.gif) 14 | stylus(str) 15 | .set('filename', path) 16 | .define('url', stylus.url({ paths: [__dirname + '/images'] })) 17 | .render(function(err, css){ 18 | if (err) throw err; 19 | console.log(css); 20 | }); -------------------------------------------------------------------------------- /test/cases/if.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 100; 3 | } 4 | body { 5 | padding: false; 6 | } 7 | body { 8 | padding: 150; 9 | } 10 | body { 11 | padding: 75; 12 | } 13 | body { 14 | padding: -1; 15 | } 16 | body { 17 | padding: 1; 18 | } 19 | body { 20 | foo: yes; 21 | foo: no; 22 | foo: zero; 23 | foo: invalid; 24 | } 25 | body .input { 26 | padding: 5px; 27 | no: margin; 28 | } 29 | body form input { 30 | foo: no; 31 | foo: bar; 32 | bar: baz; 33 | } 34 | body something { 35 | foo: bar; 36 | bar: baz; 37 | } 38 | body .nested { 39 | foo: bar; 40 | } 41 | body .nested .hidden { 42 | display: none; 43 | } -------------------------------------------------------------------------------- /test/cases/operators.complex.styl: -------------------------------------------------------------------------------- 1 | 2 | ensure-unit(n) 3 | foo bar 4 | foo bar 5 | foo bar 6 | n is a 'unit' 7 | 8 | body 9 | a = 15 10 | b = 15 11 | 12 | // yes 13 | foo a == b and (b == 15 ? 1 : 0) ? yes : no 14 | 15 | // true 16 | foo a == b and b == a 17 | 18 | // yay 19 | foo 15px is a 'unit' and #fff is a 'color'?yay:nah 20 | 21 | // nah 22 | foo 15px is a 'color' and #fff is a 'color'?yay:nah 23 | 24 | // nah 25 | foo 15px is a 'unit' and #fff is a 'unit'? yay : nah 26 | 27 | // true 28 | foo ensure-unit(15) 29 | 30 | // false 31 | foo ensure-unit(#fff) 32 | 33 | -------------------------------------------------------------------------------- /test/cases/parent.css: -------------------------------------------------------------------------------- 1 | .button { 2 | padding: 5px; 3 | -webkit-transition: opacity 1s ease-out; 4 | } 5 | .button:hover { 6 | opacity: 2; 7 | } 8 | textarea, 9 | input { 10 | color: #a7a7a7; 11 | } 12 | textarea:hover, 13 | input:hover { 14 | color: #000; 15 | } 16 | .dim { 17 | opacity: 0.2; 18 | } 19 | .dim:hover, 20 | .dim.show { 21 | opacity: 1; 22 | } 23 | body #login { 24 | -webkit-box-shadow: 1px 1px 3px #eee; 25 | -moz-box-shadow: 1px 1px 3px #eee; 26 | box-shadow: 1px 1px 3px #eee; 27 | } 28 | html.ie8 body #login, 29 | html.ie7 body #login foo, 30 | html.ie6 body #login { 31 | border: solid 1px #eee; 32 | } -------------------------------------------------------------------------------- /test/cases/parent.styl: -------------------------------------------------------------------------------- 1 | dim-on-hover() 2 | -webkit-transition opacity 1s ease-out 3 | &:hover 4 | opacity 2 5 | 6 | .button 7 | padding 5px 8 | dim-on-hover() 9 | 10 | textarea 11 | input 12 | color #A7A7A7 13 | &:hover 14 | color #000 15 | 16 | .dim 17 | opacity .2 18 | &:hover 19 | &.show 20 | opacity 1 21 | 22 | box-shadow() 23 | -webkit-box-shadow arguments 24 | -moz-box-shadow arguments 25 | box-shadow arguments 26 | html.ie8 &, 27 | html.ie7 & foo, 28 | html.ie6 & 29 | border solid 1px arguments[length(arguments) - 1] 30 | 31 | body 32 | #login 33 | box-shadow 1px 1px 3px #eee -------------------------------------------------------------------------------- /test/cases/operators.equality.styl: -------------------------------------------------------------------------------- 1 | body 2 | foo 1 == 1 3 | foo '1' == 1 4 | foo 1 == '1' 5 | foo 1 == '5' == false 6 | foo 5 == 1 == false 7 | foo 5 != 1 8 | foo 5 != asdf 9 | foo 5 == asdf == false 10 | 11 | body 12 | foo 1000ms == 1s 13 | foo 1s == 1000ms 14 | foo 1s == 500ms == false 15 | 16 | body 17 | foo wahoo == wahoo 18 | foo wahoo == 'wahoo' 19 | foo wahoo == unquote('wahoo') 20 | 21 | body 22 | foo unquote('wahoo') == wahoo 23 | foo 'wahoo' == wahoo 24 | 25 | body 26 | something = 'yay' 27 | foo yes == (something is defined ? yes : nope) 28 | foo nope == (whatever is defined ? yes : nope) -------------------------------------------------------------------------------- /test/cases/css.selectors.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 5px; 4 | } 5 | body ul { 6 | /* test */ 7 | margin: 0; 8 | } 9 | body ul li:first-child { 10 | border-top: none; 11 | } 12 | body ul li:last-child { 13 | border-bottom: none; 14 | } 15 | ul li:first-child, 16 | ul li:last-child { 17 | display: none; 18 | } 19 | foo { 20 | border-radius: 5px; 21 | } 22 | foo bar baz { 23 | border-radius: 5px; 24 | } 25 | foo, 26 | bar, 27 | baz { 28 | border-radius: 5px; 29 | } 30 | input[type=button] { 31 | border-radius: 5px; 32 | } 33 | button, 34 | input[type=button], 35 | input[type=submit], 36 | a.button { 37 | border-radius: 5px; 38 | } -------------------------------------------------------------------------------- /test/cases/selectors.styl: -------------------------------------------------------------------------------- 1 | 2 | @media print 3 | [contenteditable=true] 4 | border: none 5 | outline: none 6 | 7 | foo bar baz 8 | foo bar 9 | 10 | foo > bar 11 | foo bar 12 | 13 | input[type=text] 14 | foo bar 15 | 16 | input[type="text"] 17 | foo bar 18 | 19 | * 20 | foo bar 21 | 22 | * .foo-bar 23 | foo bar 24 | 25 | body > #container * 26 | foo bar 27 | 28 | #foo > #bar + .baz 29 | foo bar 30 | #foo>#bar 31 | foo bar 32 | 33 | p + p ~ p 34 | foo bar 35 | 36 | ul :odd 37 | foo bar 38 | 39 | ul > li:last-child 40 | foo bar 41 | 42 | ul > li:nth-child(2n) 43 | foo bar 44 | 45 | *, p + p, ul > li 46 | foo bar -------------------------------------------------------------------------------- /test/cases/property-access.css: -------------------------------------------------------------------------------- 1 | #logo { 2 | position: absolute; 3 | top: 50%; 4 | left: 50%; 5 | width: 150px; 6 | height: 80px; 7 | margin-left: -75px; 8 | margin-top: -40px; 9 | unknown: true; 10 | } 11 | multiple { 12 | foo: bar baz raz; 13 | bar: bar baz raz; 14 | } 15 | no-props { 16 | foo: ; 17 | } 18 | foo { 19 | border-color: 1px solid #ff0505; 20 | border: 1px solid #ff0505; 21 | } 22 | #logo { 23 | z-index: 20; 24 | position: absolute; 25 | } 26 | #logo2 { 27 | position: absolute; 28 | z-index: 1; 29 | } 30 | #foo { 31 | width: 200px; 32 | height: 100px; 33 | min-width: 200px; 34 | min-height: 100px; 35 | } 36 | -------------------------------------------------------------------------------- /test/cases/vargs.call.styl: -------------------------------------------------------------------------------- 1 | 2 | padding(n) 3 | padding n 4 | 5 | body 6 | padding(5px) 7 | padding(5px 10px) 8 | 9 | padding(y, x = null) 10 | padding y x 11 | 12 | body 13 | padding(5px) 14 | padding(5px, 10px) 15 | 16 | padding(args...) 17 | padding args 18 | 19 | body 20 | padding(5px) 21 | padding(5px, 10px) 22 | padding(5px, 10px, 0 2px) 23 | 24 | padding(y, rest...) 25 | test-y y 26 | if rest 27 | padding rest 28 | 29 | body 30 | padding(1px) 31 | padding(1px, 2px, 3px) 32 | 33 | padding(args...) 34 | if args 35 | test-y args[0] 36 | test-x args[1] 37 | 38 | body 39 | padding(1px) 40 | padding(1px, 2px) -------------------------------------------------------------------------------- /lib/nodes/jsliteral.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - JSLiteral 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node') 13 | , nodes = require('./'); 14 | 15 | /** 16 | * Initialize a new `JSLiteral` with the given `str`. 17 | * 18 | * @param {String} str 19 | * @api public 20 | */ 21 | 22 | var JSLiteral = module.exports = function JSLiteral(str){ 23 | Node.call(this); 24 | this.val = str; 25 | this.string = str; 26 | }; 27 | 28 | /** 29 | * Inherit from `Node.prototype`. 30 | */ 31 | 32 | JSLiteral.prototype.__proto__ = Node.prototype; 33 | -------------------------------------------------------------------------------- /test/cases/mixins.complex.css: -------------------------------------------------------------------------------- 1 | ul li { 2 | list-style-image: none; 3 | list-style-type: none; 4 | margin-left: 0; 5 | display: -moz-inline-box; 6 | -moz-box-orient: vertical; 7 | display: inline-block; 8 | vertical-align: middle; 9 | } 10 | ul li:first-child { 11 | list-style-image: none; 12 | list-style-type: none; 13 | margin-left: 0; 14 | display: -moz-inline-box; 15 | -moz-box-orient: vertical; 16 | display: inline-block; 17 | vertical-align: middle; 18 | padding-left: 5px; 19 | padding-right: 5px; 20 | } 21 | body { 22 | did: nothing; 23 | } 24 | body { 25 | padding: 5px; 26 | } 27 | body { 28 | padding: 5px; 29 | margin: 5px; 30 | } -------------------------------------------------------------------------------- /lib/nodes/comment.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Comment 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node'); 13 | 14 | /** 15 | * Initialize a new `Comment` with the given `str`. 16 | * 17 | * @param {String} str 18 | * @param {Boolean} suppress 19 | * @api public 20 | */ 21 | 22 | var Comment = module.exports = function Comment(str, suppress){ 23 | Node.call(this); 24 | this.str = str; 25 | this.suppress = suppress; 26 | }; 27 | 28 | /** 29 | * Inherit from `Node.prototype`. 30 | */ 31 | 32 | Comment.prototype.__proto__ = Node.prototype; 33 | -------------------------------------------------------------------------------- /test/cases/functions.styl: -------------------------------------------------------------------------------- 1 | 2 | add(a, b) 3 | a + b 4 | 5 | pad(x, y) 6 | padding y x y x 7 | 8 | body 9 | pad(5px, 10px) 10 | 11 | form .button 12 | padding-left add(10px, 5px) 13 | 14 | -opposite-position(pos) 15 | if pos == top 16 | bottom 17 | else if pos == bottom 18 | top 19 | else if pos == left 20 | right 21 | else if pos == right 22 | left 23 | else 24 | error('Invalid position ' + pos) 25 | 26 | opposite(positions) 27 | for pos in positions 28 | pos = -opposite-position(pos) 29 | ret = ret is defined ? ret pos : pos 30 | 31 | body 32 | foo opposite(top) 33 | foo opposite(left) 34 | foo opposite(top left) 35 | -------------------------------------------------------------------------------- /lib/visitor/index.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Visitor 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Initialize a new `Visitor` with the given `root` Node. 10 | * 11 | * @param {Node} root 12 | * @api private 13 | */ 14 | 15 | var Visitor = module.exports = function Visitor(root) { 16 | this.root = root; 17 | }; 18 | 19 | /** 20 | * Visit the given `node`. 21 | * 22 | * @param {Node|Array} node 23 | * @api public 24 | */ 25 | 26 | Visitor.prototype.visit = function(node, fn){ 27 | var method = 'visit' + node.constructor.name; 28 | if (this[method]) return this[method](node); 29 | return node; 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /test/cases/for.complex.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: a; 3 | foo: b; 4 | foo: c; 5 | foo: d; 6 | foo: e; 7 | foo: f; 8 | foo: g; 9 | } 10 | body { 11 | foo: a; 12 | } 13 | body { 14 | foo: 0 : b; 15 | foo: 1 : c; 16 | foo: 2 : d; 17 | } 18 | body { 19 | foo: error test "test"; 20 | foo: error test "foo"; 21 | } 22 | body { 23 | foo: 0 a; 24 | foo: 1 a; 25 | foo: 2 a; 26 | foo: 3 a; 27 | foo: 0 b; 28 | foo: 1 b; 29 | foo: 2 b; 30 | foo: 3 b; 31 | foo: 0 c; 32 | foo: 1 c; 33 | foo: 2 c; 34 | foo: 3 c; 35 | foo: 0 d; 36 | foo: 1 d; 37 | foo: 2 d; 38 | foo: 3 d; 39 | } 40 | body { 41 | foo: helvetica; 42 | foo: arial; 43 | foo: sans-serif; 44 | } -------------------------------------------------------------------------------- /test/cases/for.styl: -------------------------------------------------------------------------------- 1 | 2 | test(args...) 3 | test-args args 4 | for arg in args 5 | foo arg 6 | 7 | size(a, b) 8 | return a b 9 | 10 | body 11 | test 1 2 3 12 | test (1 2) (3 4) 5 13 | test size(1, 2) size(3, 4) 14 | 15 | body 16 | sizes = size(1, 2) size(3, 4) 17 | for size in sizes 18 | foo size 19 | 20 | body 21 | for n in 1..5 22 | foo n 23 | 24 | body 25 | for n in 1 2 3 26 | foo n 27 | 28 | body 29 | for n in 1 2 3 30 | foo 31 | bar n 32 | 33 | test(args...) 34 | foo 35 | for arg in args 36 | bar 37 | baz arg 38 | 39 | body 40 | test 1 2 3 41 | 42 | body 43 | for val, index in foo bar baz 44 | foo index val -------------------------------------------------------------------------------- /test/cases/regression.142.styl: -------------------------------------------------------------------------------- 1 | 2 | foo, bar, baz 3 | display none 4 | 5 | foo 6 | bar 7 | baz 8 | display none 9 | 10 | body 11 | :nth-child(2) 12 | foo bar 13 | bar 14 | baz 15 | display none 16 | 17 | body 18 | foo bar 19 | bar 20 | baz 21 | display none 22 | 23 | body 24 | foo 25 | bar 26 | baz 27 | display none 28 | 29 | body 30 | foo 31 | :nth-child(2) 32 | bar 33 | display none 34 | 35 | fn() 36 | bar if true; 37 | 38 | something() 39 | one 40 | two 41 | fn() 42 | 43 | body 44 | foo something() 45 | 46 | something() 47 | nums = 1 2 3 48 | one 49 | two 50 | for n in nums 51 | n 52 | 53 | body 54 | foo something() -------------------------------------------------------------------------------- /test/cases/bifs.push.styl: -------------------------------------------------------------------------------- 1 | 2 | nums = 1 3 | 4 | append(nums, 2) 5 | append(nums, 3, 4, 5) 6 | 7 | body 8 | foo: nums 9 | foo: nums[0] 10 | foo: nums[4] 11 | 12 | nums = 1 13 | 14 | push(nums, 2) 15 | 16 | body 17 | foo: ret = push(nums, 3, 4, 5) 18 | foo: nums[0] 19 | foo: nums[4] 20 | 21 | 22 | nums = 3 23 | 24 | body 25 | foo: unshift(nums, 2, 1) 26 | foo: nums 27 | 28 | list = () 29 | 30 | body 31 | foo: push(list, foo, bar, baz) 32 | foo: push(list, foo, bar, baz) 33 | foo: list 34 | 35 | list = (one 1) 36 | push(list, two 2, three 3) 37 | 38 | body 39 | foo: list 40 | 41 | func(list) 42 | push(list, 3,4,5) 43 | 44 | nums = 1 2 45 | func(nums) 46 | 47 | body 48 | foo: nums 49 | -------------------------------------------------------------------------------- /test/cases/css.keyframes.styl: -------------------------------------------------------------------------------- 1 | 2 | vendors = webkit 3 | 4 | animate(name) { 5 | @keyframes name { 6 | from { color: red; } 7 | to { color: blue; } 8 | } 9 | } 10 | 11 | animate(something) 12 | 13 | @-webkit-keyframes fade 14 | from 15 | opacity 0 16 | to 17 | opacity 1 18 | 19 | 20 | @keyframes bouce { 21 | from { 22 | foo: bar; 23 | } 24 | 25 | 50% { 26 | foo: bar; 27 | } 28 | 29 | to { 30 | foo: bar; 31 | } 32 | } 33 | 34 | @keyframes bouce { 35 | from { foo: bar; } 36 | 50% { foo: bar; } 37 | to { foo: bar; } 38 | } 39 | 40 | 41 | @keyframes bouce { 42 | from { foo: bar; } 43 | 44 | 45 | 50% { foo: bar; } 46 | 47 | to { foo: bar; } 48 | } 49 | -------------------------------------------------------------------------------- /test/cases/operators.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 5px; 3 | foo: 0px; 4 | foo: 0px; 5 | foo: false; 6 | foo: true; 7 | foo: 5px; 8 | foo: 1px; 9 | foo: 0; 10 | foo: false; 11 | foo: 10; 12 | foo: #fff; 13 | foo: 1; 14 | foo: true; 15 | foo: true; 16 | foo: false; 17 | foo: true; 18 | foo: true; 19 | foo: true; 20 | foo: false; 21 | foo: wahoo; 22 | foo: nope; 23 | foo: "got 15px"; 24 | foo: 1; 25 | foo: 5; 26 | foo: true; 27 | foo: true; 28 | foo: true; 29 | foo: false; 30 | foo: false; 31 | foo: false; 32 | } 33 | body { 34 | foo: <12:>; 35 | foo: <1:2>; 36 | foo: 2; 37 | foo: ; 38 | foo: X::Micrsoft::crap(#0f0); 39 | foo: ; 40 | } -------------------------------------------------------------------------------- /test/cases/arithmetic.color.styl: -------------------------------------------------------------------------------- 1 | $r = #C44444 2 | $h = hsl(#C44444) 3 | 4 | // TODO: hsl() percentages 5 | 6 | body 7 | foo: $r + 10 8 | foo: $h + 10 9 | 10 | body 11 | foo $r - 10 12 | foo $h - 10 13 | 14 | body 15 | foo $r + 20% 16 | foo $h + 20% 17 | 18 | body 19 | foo $r - 20% 20 | foo $h - 20% 21 | 22 | body 23 | foo $r + 20deg 24 | foo $h + 20deg 25 | 26 | body 27 | foo $r - 20deg 28 | foo $h - 20deg 29 | 30 | body 31 | foo $r + rgb(0,50,100) 32 | foo $h + rgb(0,50,100) 33 | 34 | body 35 | foo $r + rgb(0,50,100) 36 | foo $h - rgb(0,50,100) 37 | 38 | body 39 | foo $r + hsl(20,30,10) 40 | foo $h + hsl(20,30,10) 41 | 42 | body 43 | foo $r - hsl(20,30,10) 44 | foo $h - hsl(20,30,10) -------------------------------------------------------------------------------- /test/cases/mixins.reset.styl: -------------------------------------------------------------------------------- 1 | reset() 2 | html, body, div, span, applet, object, iframe, 3 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 4 | a, abbr, acronym, address, big, cite, code, 5 | del, dfn, em, font, img, ins, kbd, q, s, samp, 6 | small, strike, strong, sub, sup, tt, var, 7 | b, u, i, center, 8 | dl, dt, dd, ol, ul, li, 9 | fieldset, form, label, legend, 10 | table, caption, tbody, tfoot, thead, tr, th, td 11 | margin 0 12 | padding 0 13 | border 0 14 | outline 0 15 | font-size 100% 16 | vertical-align baseline 17 | background transparent 18 | 19 | reset() 20 | 21 | complex() 22 | li:nth-child(2), foo > bar, 23 | :last-child 24 | display: none 25 | 26 | ul 27 | complex() -------------------------------------------------------------------------------- /test/cases/operators.precedence.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 4; 3 | foo: 4; 4 | foo: -5px; 5 | foo: 2; 6 | foo: 2; 7 | } 8 | body { 9 | foo: true; 10 | foo: true; 11 | } 12 | body { 13 | foo: 5; 14 | foo: 5; 15 | } 16 | body { 17 | foo: true; 18 | foo: true; 19 | foo: true; 20 | foo: true; 21 | foo: 2; 22 | } 23 | body { 24 | foo: true; 25 | foo: true; 26 | } 27 | body { 28 | foo: 2.5; 29 | foo: 2.5; 30 | } 31 | body { 32 | foo: true; 33 | foo: true; 34 | foo: false; 35 | foo: wahoo; 36 | foo: fail; 37 | } 38 | body { 39 | foo: true; 40 | foo: true; 41 | } 42 | body { 43 | foo: true; 44 | foo: 1; 45 | } 46 | body { 47 | foo: true; 48 | foo: true; 49 | foo: false; 50 | foo: true; 51 | } -------------------------------------------------------------------------------- /test/cases/operators.subscript.assign.styl: -------------------------------------------------------------------------------- 1 | list = 1 2 2 | list[0] = foo 3 | list[4] = 'test' 4 | 5 | body { 6 | foo: list; 7 | foo: list[0]; 8 | foo: list[1]; 9 | foo: list[2] == null; 10 | foo: list[3] == null; 11 | foo: list[4] == 'test'; 12 | foo: length(list); 13 | } 14 | 15 | 16 | body { 17 | list = 1 2 18 | list[0] = foo 19 | list[1..3] = 'one' 20 | foo: list; 21 | } 22 | 23 | body { 24 | list = 1 25 | list[4..5] = 'two'; 26 | foo: list; 27 | } 28 | 29 | fn(list) 30 | list[2] = asdf 31 | list[3] = 'three' 32 | list 33 | 34 | body { 35 | foo: fn(1 2 3); 36 | } 37 | 38 | fn() 39 | arguments[2] = asdf 40 | arguments[3] = 'three' 41 | arguments 42 | 43 | body { 44 | foo: fn(1 2 3); 45 | } -------------------------------------------------------------------------------- /test/cases/for.css: -------------------------------------------------------------------------------- 1 | body { 2 | test-args: 1 2 3; 3 | foo: 1; 4 | foo: 2; 5 | foo: 3; 6 | test-args: 1 2 3 4 5; 7 | foo: 1 2; 8 | foo: 3 4; 9 | foo: 5; 10 | test-args: 1 2 3 4; 11 | foo: 1 2; 12 | foo: 3 4; 13 | } 14 | body { 15 | foo: 1 2; 16 | foo: 3 4; 17 | } 18 | body { 19 | foo: 1; 20 | foo: 2; 21 | foo: 3; 22 | foo: 4; 23 | foo: 5; 24 | } 25 | body { 26 | foo: 1; 27 | foo: 2; 28 | foo: 3; 29 | } 30 | body foo { 31 | bar: 1; 32 | } 33 | body foo { 34 | bar: 2; 35 | } 36 | body foo { 37 | bar: 3; 38 | } 39 | body foo bar { 40 | baz: 1; 41 | } 42 | body foo bar { 43 | baz: 2; 44 | } 45 | body foo bar { 46 | baz: 3; 47 | } 48 | body { 49 | foo: 0 foo; 50 | foo: 1 bar; 51 | foo: 2 baz; 52 | } -------------------------------------------------------------------------------- /test/cases/property-access.styl: -------------------------------------------------------------------------------- 1 | #logo 2 | position: absolute 3 | top: 50% 4 | left: 50% 5 | width: 150px 6 | height: 80px 7 | margin-left: -(@width / 2) 8 | margin-top: -(@height / 2) 9 | unknown: @something == null 10 | 11 | multiple 12 | foo: bar baz raz 13 | bar: @foo 14 | 15 | no-props 16 | foo: @bar 17 | 18 | foo 19 | border-color: @border 20 | border: 1px solid red + 5 21 | 22 | position() 23 | position: arguments 24 | z-index: 1 unless @z-index 25 | 26 | #logo 27 | z-index: 20 28 | position: absolute 29 | 30 | #logo2 31 | position: absolute 32 | 33 | min-dimensions() 34 | min-width: @width 35 | min-height: @height 36 | 37 | #foo 38 | width: 200px 39 | height: 100px 40 | min-dimensions() -------------------------------------------------------------------------------- /test/cases/selectors.css: -------------------------------------------------------------------------------- 1 | @media print { 2 | [contenteditable=true] { 3 | border: none; 4 | outline: none; 5 | } 6 | } 7 | foo bar baz { 8 | foo: bar; 9 | } 10 | foo > bar { 11 | foo: bar; 12 | } 13 | input[type=text] { 14 | foo: bar; 15 | } 16 | input[type="text"] { 17 | foo: bar; 18 | } 19 | * { 20 | foo: bar; 21 | } 22 | * .foo-bar { 23 | foo: bar; 24 | } 25 | body > #container * { 26 | foo: bar; 27 | } 28 | #foo > #bar + .baz { 29 | foo: bar; 30 | } 31 | #foo>#bar { 32 | foo: bar; 33 | } 34 | p + p ~ p { 35 | foo: bar; 36 | } 37 | ul :odd { 38 | foo: bar; 39 | } 40 | ul > li:last-child { 41 | foo: bar; 42 | } 43 | ul > li:nth-child(2n) { 44 | foo: bar; 45 | } 46 | *, 47 | p + p, 48 | ul > li { 49 | foo: bar; 50 | } -------------------------------------------------------------------------------- /test/cases/bifs.add-property.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: foo -moz-linear-gradient(#2a2a2a, #454545) bar; 3 | background: foo -webkit-gradient(linear, 0% 0%, 0% 100%, from(#2a2a2a), to(#454545)) bar; 4 | } 5 | body { 6 | background-image: -moz-linear-gradient(#2a2a2a, #454545); 7 | background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#2a2a2a), to(#454545)); 8 | } 9 | body { 10 | foo: -moz-linear-gradient(#333, #999); 11 | foo: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#333), to(#999)); 12 | } 13 | body { 14 | foo: -moz-linear-gradient(#eee, #999); 15 | foo: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#eee), to(#999)); 16 | } 17 | body { 18 | foo: -webkit-something(15px); 19 | foo: -moz-something(15px); 20 | foo: something(15px); 21 | } -------------------------------------------------------------------------------- /test/cases/vargs.styl: -------------------------------------------------------------------------------- 1 | 2 | padding(n) 3 | padding n 4 | 5 | body 6 | padding 5px 7 | padding 5px 10px 8 | 9 | padding(y, x = null) 10 | padding y x 11 | 12 | body 13 | padding 5px 14 | padding 5px 10px 15 | 16 | padding(args...) 17 | padding args 18 | 19 | body 20 | padding 5px 21 | padding 5px 10px 22 | padding 5px 10px 0 2px 23 | 24 | padding(y, rest...) 25 | test-y y 26 | if rest 27 | padding rest 28 | 29 | body 30 | padding 1px 31 | padding 1px 2px 3px 32 | 33 | padding(args...) 34 | if args 35 | test-y args[0] 36 | test-x args[1] 37 | 38 | body 39 | padding 1px 40 | padding 1px 2px 41 | 42 | padding(args...) 43 | pad args[0] 44 | pad args[1] 45 | pad args[2] 46 | len length(args) 47 | 48 | body 49 | padding 1 2 (3 4 5) -------------------------------------------------------------------------------- /test/cases/css.keyframes.css: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes something { 2 | 0% { 3 | color: #f00; 4 | } 5 | 6 | 100% { 7 | color: #00f; 8 | } 9 | } 10 | @-webkit-keyframes fade { 11 | 0% { 12 | opacity: 0; 13 | } 14 | 15 | 100% { 16 | opacity: 1; 17 | } 18 | } 19 | @-webkit-keyframes bouce { 20 | 0% { 21 | foo: bar; 22 | } 23 | 24 | 50% { 25 | foo: bar; 26 | } 27 | 28 | 100% { 29 | foo: bar; 30 | } 31 | } 32 | @-webkit-keyframes bouce { 33 | 0% { 34 | foo: bar; 35 | } 36 | 37 | 50% { 38 | foo: bar; 39 | } 40 | 41 | 100% { 42 | foo: bar; 43 | } 44 | } 45 | @-webkit-keyframes bouce { 46 | 0% { 47 | foo: bar; 48 | } 49 | 50 | 50% { 51 | foo: bar; 52 | } 53 | 54 | 100% { 55 | foo: bar; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /test/cases/mixins.complex.styl: -------------------------------------------------------------------------------- 1 | no-bullet() 2 | list-style-image none 3 | list-style-type none 4 | margin-left 0 5 | 6 | inline-block() 7 | display -moz-inline-box 8 | -moz-box-orient vertical 9 | display inline-block 10 | vertical-align middle 11 | 12 | inline-block-list-item(padding = false) 13 | no-bullet() 14 | inline-block() 15 | if padding 16 | padding-left 5px 17 | padding-right 5px 18 | 19 | ul 20 | li 21 | inline-block-list-item() 22 | 23 | ul li:first-child 24 | inline-block-list-item(true) 25 | 26 | pad(pad = false, margin = false) 27 | if pad 28 | padding 5px 29 | if margin 30 | margin 5px 31 | unless pad or margin 32 | did nothing 33 | 34 | body 35 | pad() 36 | 37 | body 38 | pad(true) 39 | 40 | body 41 | pad(true, true) -------------------------------------------------------------------------------- /test/cases/css.selectors.styl: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | margin: 0; 4 | padding: 5px; 5 | ul { 6 | /* test */ 7 | margin: 0; 8 | li:first-child { 9 | border-top: none; 10 | // test 11 | } 12 | // test 13 | li:last-child { 14 | border-bottom: none; 15 | } 16 | } 17 | } 18 | 19 | ul { 20 | li { 21 | &:first-child, 22 | &:last-child { 23 | display: none; 24 | } 25 | } 26 | } 27 | 28 | 29 | foo { 30 | border-radius: 5px; 31 | } 32 | 33 | foo bar baz { 34 | border-radius: 5px; 35 | } 36 | 37 | foo 38 | bar 39 | baz { 40 | border-radius: 5px; 41 | } 42 | 43 | input[type=button] { 44 | border-radius: 5px; 45 | } 46 | 47 | 48 | button 49 | input[type=button] 50 | input[type=submit] 51 | a.button { 52 | border-radius: 5px; 53 | } -------------------------------------------------------------------------------- /test/cases/selector.interpolation.styl: -------------------------------------------------------------------------------- 1 | form {'input'}:last-child 2 | display: none 3 | 4 | form {'input'}:nth-child({10 + 5}) 5 | display: none 6 | 7 | for n in 1 2 3 4 5 8 | .grid-{n} 9 | width: unit(n * 100, 'px') 10 | 11 | pos = last 12 | 13 | body {form} 14 | input:{ pos }-child 15 | display: none 16 | 17 | mixin(n) 18 | &:nth-child({ n }) 19 | display: none 20 | 21 | ul li 22 | mixin(2) 23 | 24 | {foo} {bar} 25 | foo: bar 26 | 27 | {foo} 28 | {bar} 29 | {baz} 30 | foo: bar 31 | 32 | {foo} 33 | {bar} 34 | {baz} 35 | {foo}: bar 36 | {one} 1 37 | {two} 2 38 | 39 | selectors = one two three 40 | props = (one 1) (two 2) (three 3) 41 | 42 | for selector in selectors 43 | {selector} * 44 | for prop in props 45 | {prop[0]}: prop[1] 46 | -------------------------------------------------------------------------------- /test/cases/selectors.pseudo.css: -------------------------------------------------------------------------------- 1 | ul td:nth-of-type(2), 2 | ul td:nth-of-type(3) { 3 | background: #000; 4 | } 5 | table td:nth-child(2), 6 | table td:nth-child(3), 7 | table td:nth-child(4), 8 | table td:nth-child(5), 9 | table td:first-letter { 10 | background: #000; 11 | } 12 | table td:nth-child(2) li:first-child, 13 | table td:nth-child(3) li:first-child, 14 | table td:nth-child(4) li:first-child, 15 | table td:nth-child(5) li:first-child, 16 | table td:first-letter li:first-child, 17 | table td:nth-child(2) li:last-child, 18 | table td:nth-child(3) li:last-child, 19 | table td:nth-child(4) li:last-child, 20 | table td:nth-child(5) li:last-child, 21 | table td:first-letter li:last-child { 22 | background: #fff; 23 | } 24 | table :nth-child(2), 25 | table :nth-child(3) { 26 | background: #000; 27 | } -------------------------------------------------------------------------------- /lib/nodes/media.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Media 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node') 13 | , nodes = require('./'); 14 | 15 | /** 16 | * Initialize a new `Media` with the given `val` 17 | * 18 | * @param {String} val 19 | * @api public 20 | */ 21 | 22 | var Media = module.exports = function Media(val){ 23 | Node.call(this); 24 | this.val = val; 25 | }; 26 | 27 | /** 28 | * Inherit from `Node.prototype`. 29 | */ 30 | 31 | Media.prototype.__proto__ = Node.prototype; 32 | 33 | /** 34 | * Return @media "val". 35 | * 36 | * @return {String} 37 | * @api public 38 | */ 39 | 40 | Media.prototype.toString = function(){ 41 | return '@media ' + this.val; 42 | }; 43 | -------------------------------------------------------------------------------- /test/cases/reset.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | div, 4 | span, 5 | applet, 6 | object, 7 | iframe, 8 | h1, 9 | h2, 10 | h3, 11 | h4, 12 | h5, 13 | h6, 14 | p, 15 | blockquote, 16 | pre, 17 | a, 18 | abbr, 19 | acronym, 20 | address, 21 | big, 22 | cite, 23 | code, 24 | del, 25 | dfn, 26 | em, 27 | font, 28 | img, 29 | ins, 30 | kbd, 31 | q, 32 | s, 33 | samp, 34 | small, 35 | strike, 36 | strong, 37 | sub, 38 | sup, 39 | tt, 40 | var, 41 | b, 42 | u, 43 | i, 44 | center, 45 | dl, 46 | dt, 47 | dd, 48 | ol, 49 | ul, 50 | li, 51 | fieldset, 52 | form, 53 | label, 54 | legend, 55 | table, 56 | caption, 57 | tbody, 58 | tfoot, 59 | thead, 60 | tr, 61 | th, 62 | td { 63 | margin: 0; 64 | padding: 0; 65 | border: 0; 66 | outline: 0; 67 | font-size: 100%; 68 | vertical-align: baseline; 69 | background: transparent; 70 | } -------------------------------------------------------------------------------- /lib/nodes/charset.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Charset 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node') 13 | , nodes = require('./'); 14 | 15 | /** 16 | * Initialize a new `Charset` with the given `val` 17 | * 18 | * @param {String} val 19 | * @api public 20 | */ 21 | 22 | var Charset = module.exports = function Charset(val){ 23 | Node.call(this); 24 | this.val = val; 25 | }; 26 | 27 | /** 28 | * Inherit from `Node.prototype`. 29 | */ 30 | 31 | Charset.prototype.__proto__ = Node.prototype; 32 | 33 | /** 34 | * Return @charset "val". 35 | * 36 | * @return {String} 37 | * @api public 38 | */ 39 | 40 | Charset.prototype.toString = function(){ 41 | return '@charset ' + this.val; 42 | }; 43 | -------------------------------------------------------------------------------- /test/cases/interpolation.properties.css: -------------------------------------------------------------------------------- 1 | #login { 2 | -webkit-border-radius: 1px 2px/3px 4px; 3 | -moz-border-radius: 1px 2px/3px 4px; 4 | border-radius: 1px 2px/3px 4px; 5 | } 6 | body { 7 | foo: bar; 8 | foo-something: foo; 9 | foo-something-bar: foo; 10 | something-foo: foo; 11 | something: foo; 12 | } 13 | body { 14 | test-stuff-yup: awesome; 15 | -webkit-border-radius: awesome; 16 | -webkit-box-shadow: awesome; 17 | } 18 | body { 19 | foo: "one"; 20 | foo: "two"; 21 | } 22 | body { 23 | -webkit-something: foo; 24 | something: foo; 25 | } 26 | body form input { 27 | -webkit-something: foo; 28 | something: foo; 29 | } 30 | body form input p { 31 | something: foo; 32 | } 33 | body { 34 | foo-test-baz: bar; 35 | foo-test: bar; 36 | test: bar; 37 | position: absolute; 38 | top: 0; 39 | right: 0; 40 | } -------------------------------------------------------------------------------- /test/cases/if.postfix.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: 1; 3 | foo: 2; 4 | foo: 3; 5 | foo: 4; 6 | foo: 5; 7 | foo: 6; 8 | foo: 7; 9 | } 10 | body { 11 | foo: 3; 12 | } 13 | body { 14 | foo: true; 15 | foo: true; 16 | } 17 | body { 18 | foo: true; 19 | foo: true; 20 | } 21 | body { 22 | foo: 5; 23 | } 24 | body { 25 | foo: bar; 26 | foo: baz; 27 | } 28 | body { 29 | foo: bar; 30 | foo: baz; 31 | } 32 | @import "foo.css"; 33 | body { 34 | foo: 5; 35 | } 36 | body { 37 | foo: string; 38 | foo: number; 39 | foo: unknown; 40 | } 41 | body { 42 | foo: true; 43 | foo: true; 44 | foo: false; 45 | } 46 | body { 47 | fonts: arial, sans-serif; 48 | } 49 | body { 50 | foo: yes; 51 | foo: yes; 52 | foo: yes; 53 | foo: ; 54 | foo: ; 55 | } 56 | body { 57 | foo: yes; 58 | foo: no; 59 | foo: zero; 60 | foo: invalid; 61 | } -------------------------------------------------------------------------------- /test/cases/selector.interpolation.css: -------------------------------------------------------------------------------- 1 | form input:last-child { 2 | display: none; 3 | } 4 | form input:nth-child(15) { 5 | display: none; 6 | } 7 | .grid-1 { 8 | width: 100px; 9 | } 10 | .grid-2 { 11 | width: 200px; 12 | } 13 | .grid-3 { 14 | width: 300px; 15 | } 16 | .grid-4 { 17 | width: 400px; 18 | } 19 | .grid-5 { 20 | width: 500px; 21 | } 22 | body form input:last-child { 23 | display: none; 24 | } 25 | ul li:nth-child(2) { 26 | display: none; 27 | } 28 | foo bar { 29 | foo: bar; 30 | } 31 | foo bar baz { 32 | foo: bar; 33 | } 34 | foo { 35 | two: 2; 36 | } 37 | foo bar { 38 | one: 1; 39 | } 40 | foo bar baz { 41 | foo: bar; 42 | } 43 | one * { 44 | one: 1; 45 | two: 2; 46 | three: 3; 47 | } 48 | two * { 49 | one: 1; 50 | two: 2; 51 | three: 3; 52 | } 53 | three * { 54 | one: 1; 55 | two: 2; 56 | three: 3; 57 | } -------------------------------------------------------------------------------- /test/cases/operators.subscript.css: -------------------------------------------------------------------------------- 1 | body { 2 | foo: true; 3 | foo: 3 4 5; 4 | foo: true; 5 | foo: true; 6 | foo: false; 7 | foo: -5; 8 | } 9 | body { 10 | foo: 1 2 3 4; 11 | foo: 1; 12 | foo: 2 3 4; 13 | foo: 2; 14 | foo: 3 4; 15 | foo: 3; 16 | foo: 4; 17 | foo: ; 18 | } 19 | body { 20 | foo: error; 21 | foo: "message"; 22 | } 23 | body { 24 | foo: 5; 25 | foo: 10; 26 | } 27 | body { 28 | foo: 5; 29 | foo: 10; 30 | } 31 | body { 32 | foo: 1 2; 33 | foo: 3 4; 34 | foo: 4; 35 | } 36 | body { 37 | foo: 100 200; 38 | foo: 100; 39 | foo: 200; 40 | foo: 2; 41 | } 42 | body { 43 | foo: 100 200; 44 | foo: 100; 45 | foo: 200; 46 | foo: 2; 47 | } 48 | body { 49 | foo: 100 200; 50 | foo: 100; 51 | foo: 200; 52 | foo: 2; 53 | } 54 | body { 55 | foo: 100 200; 56 | foo: 100; 57 | foo: 200; 58 | foo: 2; 59 | } -------------------------------------------------------------------------------- /test/cases/selectors.pseudo.elements.css: -------------------------------------------------------------------------------- 1 | input::selection, 2 | input::focus-inner, 3 | input::-moz-selection, 4 | input::-webkit-selection, 5 | input::-moz-focus-inner, 6 | input::-webkit-focus-inner { 7 | border: 0; 8 | padding: 0; 9 | } 10 | input::-moz-selection { 11 | border: 0; 12 | } 13 | p, 14 | ::selection, 15 | ::-moz-selection, 16 | ::-webkit-selection { 17 | background: #000; 18 | } 19 | ::selection, 20 | ::-moz-selection, 21 | ::-webkit-selection { 22 | background: #000; 23 | } 24 | p::selection, 25 | a::selection, 26 | p::-moz-selection, 27 | p::-webkit-selection, 28 | a::-moz-selection, 29 | a::-webkit-selection { 30 | background: #000; 31 | } 32 | p::selection, 33 | p::-moz-selection, 34 | p::-webkit-selection { 35 | color: #fff; 36 | background: #000; 37 | } 38 | body ::selection, 39 | body ::-webkit-selection { 40 | color: #fff; 41 | } -------------------------------------------------------------------------------- /lib/nodes/page.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Page 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node'); 13 | 14 | /** 15 | * Initialize a new `Page` with the given `selector` and `block`. 16 | * 17 | * @param {Selector} selector 18 | * @param {Block} block 19 | * @api public 20 | */ 21 | 22 | var Page = module.exports = function Page(selector, block){ 23 | Node.call(this); 24 | this.selector = selector; 25 | this.block = block; 26 | }; 27 | 28 | /** 29 | * Inherit from `Node.prototype`. 30 | */ 31 | 32 | Page.prototype.__proto__ = Node.prototype; 33 | 34 | /** 35 | * Return `@oage name`. 36 | * 37 | * @return {String} 38 | * @api public 39 | */ 40 | 41 | Page.prototype.toString = function(){ 42 | return '@page ' + this.selector; 43 | }; 44 | -------------------------------------------------------------------------------- /lib/nodes/root.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Root 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node'); 13 | 14 | /** 15 | * Initialize a new `Root` node. 16 | * 17 | * @api public 18 | */ 19 | 20 | var Root = module.exports = function Root(){ 21 | this.nodes = []; 22 | }; 23 | 24 | /** 25 | * Inherit from `Node.prototype`. 26 | */ 27 | 28 | Root.prototype.__proto__ = Node.prototype; 29 | 30 | /** 31 | * Push a `node` to this block. 32 | * 33 | * @param {Node} node 34 | * @api public 35 | */ 36 | 37 | Root.prototype.push = function(node){ 38 | this.nodes.push(node); 39 | }; 40 | 41 | /** 42 | * Return "root". 43 | * 44 | * @return {String} 45 | * @api public 46 | */ 47 | 48 | Root.prototype.toString = function(){ 49 | return '[Root]'; 50 | }; 51 | -------------------------------------------------------------------------------- /test/cases/operators.in.styl: -------------------------------------------------------------------------------- 1 | 2 | 3 | body 4 | nums = 1 2 3 5 | foo 1 in nums 6 | foo 3 in nums 7 | foo 5 in nums 8 | 9 | body 10 | nums = 1 11 | foo 1 in nums == true 12 | 13 | body 14 | words = foo bar baz 15 | foo bar in words 16 | foo baz in words 17 | foo HEY in words 18 | 19 | body 20 | tuples = (test 'one') (test 'two') 2 21 | foo test in tuples 22 | foo 2 in tuples 23 | foo (test 'one') in tuples 24 | foo (test 'two') in tuples 25 | foo (test 'something') in tuples 26 | 27 | fn(args...) 28 | 2 in args 29 | 30 | body 31 | foo fn() 32 | foo fn(1) 33 | foo fn(2) 34 | foo fn(3 2) 35 | foo fn(1,2,3) 36 | 37 | fn(args...) 38 | (3 2) in args 39 | 40 | body 41 | foo fn(3 2) 42 | foo fn(3,2) 43 | 44 | fn() 45 | test in arguments 46 | 47 | body 48 | foo fn(test) 49 | foo fn(a, b, c) 50 | foo fn(a, test, c) 51 | foo fn(a test c) -------------------------------------------------------------------------------- /test/cases/mixins.reset.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | div, 4 | span, 5 | applet, 6 | object, 7 | iframe, 8 | h1, 9 | h2, 10 | h3, 11 | h4, 12 | h5, 13 | h6, 14 | p, 15 | blockquote, 16 | pre, 17 | a, 18 | abbr, 19 | acronym, 20 | address, 21 | big, 22 | cite, 23 | code, 24 | del, 25 | dfn, 26 | em, 27 | font, 28 | img, 29 | ins, 30 | kbd, 31 | q, 32 | s, 33 | samp, 34 | small, 35 | strike, 36 | strong, 37 | sub, 38 | sup, 39 | tt, 40 | var, 41 | b, 42 | u, 43 | i, 44 | center, 45 | dl, 46 | dt, 47 | dd, 48 | ol, 49 | ul, 50 | li, 51 | fieldset, 52 | form, 53 | label, 54 | legend, 55 | table, 56 | caption, 57 | tbody, 58 | tfoot, 59 | thead, 60 | tr, 61 | th, 62 | td { 63 | margin: 0; 64 | padding: 0; 65 | border: 0; 66 | outline: 0; 67 | font-size: 100%; 68 | vertical-align: baseline; 69 | background: transparent; 70 | } 71 | ul li:nth-child(2), 72 | ul foo > bar, 73 | ul :last-child { 74 | display: none; 75 | } -------------------------------------------------------------------------------- /lib/nodes/return.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Return 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node') 13 | , nodes = require('./'); 14 | 15 | /** 16 | * Initialize a new `Return` node with the given `expr`. 17 | * 18 | * @param {Expression} expr 19 | * @api public 20 | */ 21 | 22 | var Return = module.exports = function Return(expr){ 23 | this.expr = expr || nodes.null; 24 | }; 25 | 26 | /** 27 | * Inherit from `Node.prototype`. 28 | */ 29 | 30 | Return.prototype.__proto__ = Node.prototype; 31 | 32 | /** 33 | * Return a clone of this node. 34 | * 35 | * @return {Node} 36 | * @api public 37 | */ 38 | 39 | Return.prototype.clone = function(){ 40 | var clone = new Return(this.expr.clone()); 41 | clone.lineno = this.lineno; 42 | clone.filename = this.filename; 43 | return clone; 44 | }; -------------------------------------------------------------------------------- /docs/comments.md: -------------------------------------------------------------------------------- 1 | 2 | ## Comments 3 | 4 | Stylus supports three kinds of comments, single-line, and multi-line comments, and multi-line buffered comments. 5 | 6 | ## Single-line 7 | 8 | Single-line comments look like JavaScript comments, and do not output in the resulting CSS: 9 | 10 | // I'm a comment! 11 | body 12 | padding 5px // some awesome padding 13 | 14 | ## Multi-line 15 | 16 | Multi-line comments look identical to regular CSS comments, however they only output when the `compress` option is not enabled. 17 | 18 | /* 19 | * Adds the given numbers together. 20 | */ 21 | 22 | add(a, b) 23 | a + b 24 | 25 | ## Multi-line buffered 26 | 27 | Multi-line comments which are not suppressed start with `/*!`, signalling Stylus to output the comment regardless of compression. 28 | 29 | /*! 30 | * Adds the given numbers together. 31 | */ 32 | 33 | add(a, b) 34 | a + b 35 | 36 | -------------------------------------------------------------------------------- /lib/nodes/unaryop.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - UnaryOp 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node'); 13 | 14 | /** 15 | * Initialize a new `UnaryOp` with `op`, and `expr`. 16 | * 17 | * @param {String} op 18 | * @param {Node} expr 19 | * @api public 20 | */ 21 | 22 | var UnaryOp = module.exports = function UnaryOp(op, expr){ 23 | Node.call(this); 24 | this.op = op; 25 | this.expr = expr; 26 | }; 27 | 28 | /** 29 | * Inherit from `Node.prototype`. 30 | */ 31 | 32 | UnaryOp.prototype.__proto__ = Node.prototype; 33 | 34 | /** 35 | * Return a clone of this node. 36 | * 37 | * @return {Node} 38 | * @api public 39 | */ 40 | 41 | UnaryOp.prototype.clone = function(){ 42 | var clone = new UnaryOp(this.op, this.expr.clone()); 43 | clone.lineno = this.lineno; 44 | clone.filename = this.filename; 45 | return clone; 46 | }; -------------------------------------------------------------------------------- /editors/Stylus.tmbundle/Commands/Compile and Display CSS.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/bin/bash 9 | 10 | function highlight { 11 | test `which pygmentize` 12 | if [[ $? -eq 0 ]]; then 13 | pygmentize -Onoclasses,nobackground=True -l css -f html 14 | else 15 | pre 16 | fi 17 | } 18 | 19 | ${TM_STYLUS:=stylus} | highlight 20 | input 21 | selection 22 | keyEquivalent 23 | @b 24 | name 25 | Compile and Display CSS 26 | output 27 | showAsHTML 28 | scope 29 | source.stylus 30 | uuid 31 | DD8F8C2B-2B83-4734-82EE-8508EE344638 32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/builtins.styl: -------------------------------------------------------------------------------- 1 | 2 | 3 | // color manipulation 4 | 5 | body 6 | color darken(#eee, 50) 7 | color darken(#eee, 50%) 8 | color #eee - rgba(100,0,0,0.5) 9 | color rgba(#eee,.5) 10 | 11 | // expression node access 12 | 13 | body 14 | list = (one 1) (two 2) (three 3) 15 | foo last(list) 16 | 17 | // pseudo hashes 18 | 19 | get(hash, key) 20 | return pair[1] if pair[0] == key for pair in hash 21 | 22 | body 23 | hash = (one 1) (two 2) (three 3) 24 | foo get(hash, two) 25 | foo get(hash, one) 26 | foo get(hash, none) == null 27 | foo length(hash) 28 | 29 | // color components 30 | 31 | body 32 | foo red(#c00) 33 | foo lightness(#c00) 34 | 35 | // units 36 | 37 | body 38 | foo unit(15%) 39 | foo unit(15%, px) 40 | foo unit(15px, '%') 41 | 42 | // math 43 | 44 | body 45 | foo abs(-5) 46 | foo sum(1 2 3 4) 47 | foo avg(1 2 3 4) 48 | 49 | // literals 50 | 51 | body 52 | foo unquote('X::MessedUp::IE.crap(here)') 53 | 54 | // inspection 55 | 56 | p(1 + 5 / 10) -------------------------------------------------------------------------------- /test/cases/css.mixins.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Reset button related properties so that 3 | * a, button, and input's are supported. 4 | */ 5 | /* 6 | * Minimalistic flat button with white inset. 7 | */ 8 | button, 9 | a.button { 10 | display: block; 11 | text-decoration: none; 12 | background: #e3e3e3; 13 | border: 1px solid #bdbdbd; 14 | border-radius: 3px; 15 | box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.80); 16 | color: #333; 17 | font-family: "helvetica neue", helvetica, arial, sans-serif; 18 | font-size: 12px; 19 | font-weight: bold; 20 | line-height: 1; 21 | padding: 8px 0 9px; 22 | text-align: center; 23 | text-shadow: 0 1px 0 #fff; 24 | width: 150px; 25 | } 26 | button:hover, 27 | a.button:hover { 28 | background: #dbdbdb; 29 | box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.50); 30 | color: #222; 31 | cursor: pointer; 32 | } 33 | button:active, 34 | a.button:active { 35 | background: #d6d6d6; 36 | box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.20); 37 | color: #000; 38 | } -------------------------------------------------------------------------------- /editors/Stylus.tmbundle/Preferences/Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Comments 7 | scope 8 | source.stylus 9 | settings 10 | 11 | shellVariables 12 | 13 | 14 | name 15 | TM_COMMENT_START 16 | value 17 | // 18 | 19 | 20 | name 21 | TM_COMMENT_START_2 22 | value 23 | /* 24 | 25 | 26 | name 27 | TM_COMMENT_END_2 28 | value 29 | */ 30 | 31 | 32 | 33 | uuid 34 | 7EC85265-178C-4ECC-AAE2-4EEF4AFF8872 35 | 36 | 37 | -------------------------------------------------------------------------------- /test/cases/css.mixins.braces.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Reset button related properties so that 3 | * a, button, and input's are supported. 4 | */ 5 | /* 6 | * Minimalistic flat button with white inset. 7 | */ 8 | button, 9 | a.button { 10 | display: block; 11 | text-decoration: none; 12 | background: #e3e3e3; 13 | border: 1px solid #bdbdbd; 14 | border-radius: 3px; 15 | box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.80); 16 | color: #333; 17 | font-family: "helvetica neue", helvetica, arial, sans-serif; 18 | font-size: 12px; 19 | font-weight: bold; 20 | line-height: 1; 21 | padding: 8px 0 9px; 22 | text-align: center; 23 | text-shadow: 0 1px 0 #fff; 24 | width: 150px; 25 | } 26 | button:hover, 27 | a.button:hover { 28 | background: #dbdbdb; 29 | box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.50); 30 | color: #222; 31 | cursor: pointer; 32 | } 33 | button:active, 34 | a.button:active { 35 | background: #d6d6d6; 36 | box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.20); 37 | color: #000; 38 | } -------------------------------------------------------------------------------- /test/cases/for.function.styl: -------------------------------------------------------------------------------- 1 | 2 | sum(nums...) 3 | sum = 0 4 | for n in nums 5 | sum += n 6 | 7 | sum2(nums...) 8 | sum = 0 9 | for n in nums 10 | sum += n 11 | sum * 2 12 | 13 | sum3(nums...) 14 | sum = 0 15 | sum += n for n in nums 16 | 17 | body 18 | foo sum(1,2,3,4) 19 | foo sum2(1,2,3,4) 20 | foo sum3(1,2,3,4) 21 | 22 | join(delim, args) 23 | buf = '' 24 | for arg, i in args 25 | buf += i ? delim + arg : arg 26 | 27 | join2(delim, args) 28 | buf = '' 29 | buf += i ? delim + arg : arg for arg, i in args 30 | 31 | body 32 | foo join(' ', foo bar baz) 33 | foo join(', ', foo bar baz) 34 | foo join2(' ', 1 2 3) 35 | foo join2(', ', 1 2 3) 36 | 37 | body 38 | fonts = Impact Arial sans-serif 39 | for font, i in fonts 40 | foo i font 41 | 42 | last-even(nums...) 43 | ret = n if n % 2 == 0 for n in nums 44 | ret 45 | 46 | first-even(nums...) 47 | return n if n % 2 == 0 for n in nums 48 | 49 | body 50 | foo last-even(1,3,30,5,6,12,2,24,3) 51 | foo first-even(1,3,30,5,6,12,2,24,3) -------------------------------------------------------------------------------- /docs/pseudo-elements.md: -------------------------------------------------------------------------------- 1 | 2 | ## Pseudo Elements 3 | 4 | Stylus support for pseudo elements automatically expands 5 | through the use of the `vendors` variable, defaulting to "webkit", 6 | "moz", and "official". This means that when you write selectors using 7 | `::selection` etc they will automatically be expanded to vendor prefixed 8 | versions. 9 | 10 | p::selection { 11 | color: white; 12 | background: black; 13 | } 14 | 15 | yields: 16 | 17 | p::selection, 18 | p::-moz-selection, 19 | p::-webkit-selection { 20 | color: #fff; 21 | background: #000; 22 | } 23 | 24 | 25 | Much like the Stylus __@keyframes__ support you may alter `vendors` at any 26 | time in order to change this behaviour: 27 | 28 | vendors = webkit 29 | 30 | p::selection { 31 | color: white; 32 | background: black; 33 | } 34 | 35 | yields: 36 | 37 | p::selection, 38 | p::-webkit-selection { 39 | color: #fff; 40 | background: #000; 41 | } 42 | -------------------------------------------------------------------------------- /test/cases/interpolation.properties.styl: -------------------------------------------------------------------------------- 1 | 2 | vendor(prop, args) 3 | -webkit-{prop} args 4 | -moz-{prop} args 5 | {prop} args 6 | 7 | border-radius() 8 | vendor('border-radius', arguments) 9 | 10 | #login 11 | border-radius 1px 2px / 3px 4px 12 | 13 | body 14 | prop = 'something' 15 | foo bar 16 | foo-{prop} foo 17 | foo-{prop}-bar foo 18 | {prop}-foo foo 19 | {prop} foo 20 | 21 | body 22 | {'test' + '-stuff'}-yup awesome 23 | -webkit-{border-radius} awesome 24 | -webkit-{box-shadow} awesome 25 | 26 | testing(var, one, two) 27 | {var} 28 | 29 | body 30 | foo testing('one', 1, 2) 31 | foo testing('two', 1, 2) 32 | 33 | body 34 | nested(prop) 35 | -webkit-{prop} foo 36 | {prop} foo 37 | form input 38 | -webkit-{prop} foo 39 | {prop} foo 40 | p 41 | {prop} foo 42 | nested('something') 43 | 44 | top-right() 45 | position absolute 46 | top 0 47 | right 0 48 | 49 | foo(ret) 50 | ret 51 | 52 | body 53 | foo-{foo('test')}-baz bar 54 | foo-{foo('test')} bar 55 | {foo('test')} bar 56 | {foo('top')}-right bar 57 | -------------------------------------------------------------------------------- /docs/kwargs.md: -------------------------------------------------------------------------------- 1 | 2 | ## Keyword Arguments 3 | 4 | Stylus supports keyword arguments, or "kwargs", allowing you to key 5 | arguments by their associated parameter name. 6 | 7 | The examples shown below are functionally equivalent, however we can 8 | place keyword arguments anywhere within the list. The remaining arguments 9 | that are _not_ keyed will be applied to the parameters that have not 10 | been satisfied. 11 | 12 | body { 13 | color: rgba(255, 200, 100, 0.5); 14 | color: rgba(red: 255, green: 200, blue: 100, alpha: 0.5); 15 | color: rgba(alpha: 0.5, blue: 100, red: 255, 200); 16 | color: rgba(alpha: 0.5, blue: 100, 255, 200); 17 | } 18 | 19 | yielding: 20 | 21 | body { 22 | color: rgba(255,200,100,0.5); 23 | color: rgba(255,200,100,0.5); 24 | color: rgba(255,200,100,0.5); 25 | color: rgba(255,200,100,0.5); 26 | } 27 | 28 | 29 | To see what parameters a function or mixin accept, use the `p()` function: 30 | 31 | p(rgba) 32 | 33 | yielding: 34 | 35 | inspect: rgba(red, green, blue, alpha) 36 | -------------------------------------------------------------------------------- /lib/stack/scope.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - stack - Scope 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Initialize a new `Scope`. 10 | * 11 | * @api private 12 | */ 13 | 14 | var Scope = module.exports = function Scope() { 15 | this.locals = {}; 16 | }; 17 | 18 | /** 19 | * Add `ident` node to the current scope. 20 | * 21 | * @param {Ident} ident 22 | * @api private 23 | */ 24 | 25 | Scope.prototype.add = function(ident){ 26 | this.locals[ident.name] = ident.val; 27 | }; 28 | 29 | /** 30 | * Lookup the given local variable `name`. 31 | * 32 | * @param {String} name 33 | * @return {Node} 34 | * @api private 35 | */ 36 | 37 | Scope.prototype.lookup = function(name){ 38 | return this.locals[name]; 39 | }; 40 | 41 | /** 42 | * Custom inspect. 43 | * 44 | * @return {String} 45 | * @api public 46 | */ 47 | 48 | Scope.prototype.inspect = function(){ 49 | var keys = Object.keys(this.locals).map(function(key){ return '@' + key; }); 50 | return '[Scope' 51 | + (keys.length ? ' ' + keys.join(', ') : '') 52 | + ']'; 53 | }; 54 | -------------------------------------------------------------------------------- /lib/nodes/fontface.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - FontFace 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node'); 13 | 14 | /** 15 | * Initialize a new `FontFace` with the given `block`. 16 | * 17 | * @param {Block} block 18 | * @api public 19 | */ 20 | 21 | var FontFace = module.exports = function FontFace(block){ 22 | Node.call(this); 23 | this.block = block; 24 | }; 25 | 26 | /** 27 | * Inherit from `Node.prototype`. 28 | */ 29 | 30 | FontFace.prototype.__proto__ = Node.prototype; 31 | 32 | /** 33 | * Return a clone of this node. 34 | * 35 | * @return {Node} 36 | * @api public 37 | */ 38 | 39 | FontFace.prototype.clone = function(){ 40 | var clone = new FontFace(this.block.clone()); 41 | clone.lineno = this.lineno; 42 | clone.filename = this.filename; 43 | return clone; 44 | }; 45 | 46 | /** 47 | * Return `@oage name`. 48 | * 49 | * @return {String} 50 | * @api public 51 | */ 52 | 53 | FontFace.prototype.toString = function(){ 54 | return '@font-face'; 55 | }; 56 | -------------------------------------------------------------------------------- /docs/introspection.md: -------------------------------------------------------------------------------- 1 | 2 | ## Introspection API 3 | 4 | Stylus supports an introspection API, allowing mixins and functions to reflect relative to the caller etc. 5 | 6 | 7 | ## mixin 8 | 9 | The `mixin` local variable is automatically assigned within function bodies, 10 | containing the string "root" indicating the function is called at the root 11 | level, or "block" indicating otherwise, and finally `false` if the function 12 | is invoked expecting a return value. 13 | 14 | In the following example we define `reset()` altering its behaviour when mixed in to root, another block, or a return value as used in the `foo` property below. 15 | 16 | reset() 17 | if mixin == 'root' 18 | got 19 | root true 20 | else if mixin 21 | got 'a mixin' 22 | else 23 | 'not a mixin' 24 | 25 | reset() 26 | 27 | body 28 | reset() 29 | foo reset() 30 | 31 | compiles to: 32 | 33 | got { 34 | root: true; 35 | } 36 | body { 37 | foo: "not a mixin"; 38 | got: "a mixin"; 39 | } 40 | -------------------------------------------------------------------------------- /lib/token.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Token 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var inspect = require('sys').inspect; 13 | 14 | /** 15 | * Initialize a new `Token` with the given `type` and `val`. 16 | * 17 | * @param {String} type 18 | * @param {Mixed} val 19 | * @api private 20 | */ 21 | 22 | var Token = exports = module.exports = function Token(type, val) { 23 | this.type = type; 24 | this.val = val; 25 | }; 26 | 27 | /** 28 | * Custom inspect. 29 | * 30 | * @return {String} 31 | * @api public 32 | */ 33 | 34 | Token.prototype.inspect = function(){ 35 | var val = ' ' + inspect(this.val); 36 | return '[Token:' + this.lineno + ' ' 37 | + '\x1b[32m' + this.type + '\x1b[0m' 38 | + '\x1b[33m' + (this.val ? val : '') + '\x1b[0m' 39 | + ']'; 40 | }; 41 | 42 | /** 43 | * Return type or val. 44 | * 45 | * @return {String} 46 | * @api public 47 | */ 48 | 49 | Token.prototype.toString = function(){ 50 | return (undefined === this.val 51 | ? this.type 52 | : this.val).toString(); 53 | }; 54 | -------------------------------------------------------------------------------- /lib/nodes/call.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Call 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node'); 13 | 14 | /** 15 | * Initialize a new `Call` with `name` and `args`. 16 | * 17 | * @param {String} name 18 | * @param {Expression} args 19 | * @api public 20 | */ 21 | 22 | var Call = module.exports = function Call(name, args){ 23 | Node.call(this); 24 | this.name = name; 25 | this.args = args; 26 | }; 27 | 28 | /** 29 | * Inherit from `Node.prototype`. 30 | */ 31 | 32 | Call.prototype.__proto__ = Node.prototype; 33 | 34 | /** 35 | * Return a clone of this node. 36 | * 37 | * @return {Node} 38 | * @api public 39 | */ 40 | 41 | Call.prototype.clone = function(){ 42 | var clone = new Call(this.name, this.args.clone()); 43 | clone.lineno = this.lineno; 44 | clone.filename = this.filename; 45 | return clone; 46 | }; 47 | 48 | /** 49 | * Return (). 50 | * 51 | * @return {String} 52 | * @api public 53 | */ 54 | 55 | Call.prototype.toString = function(){ 56 | return this.name + '()'; 57 | }; -------------------------------------------------------------------------------- /lib/nodes/binop.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - BinOp 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node'); 13 | 14 | /** 15 | * Initialize a new `BinOp` with `op`, `left` and `right`. 16 | * 17 | * @param {String} op 18 | * @param {Node} left 19 | * @param {Node} right 20 | * @api public 21 | */ 22 | 23 | var BinOp = module.exports = function BinOp(op, left, right){ 24 | Node.call(this); 25 | this.op = op; 26 | this.left = left; 27 | this.right = right; 28 | }; 29 | 30 | /** 31 | * Inherit from `Node.prototype`. 32 | */ 33 | 34 | BinOp.prototype.__proto__ = Node.prototype; 35 | 36 | /** 37 | * Return a clone of this node. 38 | * 39 | * @return {Node} 40 | * @api public 41 | */ 42 | 43 | BinOp.prototype.clone = function(){ 44 | var clone = new BinOp( 45 | this.op 46 | , this.left.clone() 47 | , this.right ? 48 | this.right.clone() 49 | : null); 50 | clone.lineno = this.lineno; 51 | clone.filename = this.filename; 52 | if (this.val) clone.val = this.val.clone(); 53 | return clone; 54 | }; -------------------------------------------------------------------------------- /lib/nodes/ternary.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Ternary 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node'); 13 | 14 | /** 15 | * Initialize a new `Ternary` with `cond`, `trueExpr` and `falseExpr`. 16 | * 17 | * @param {Expression} cond 18 | * @param {Expression} trueExpr 19 | * @param {Expression} falseExpr 20 | * @api public 21 | */ 22 | 23 | var Ternary = module.exports = function Ternary(cond, trueExpr, falseExpr){ 24 | Node.call(this); 25 | this.cond = cond; 26 | this.trueExpr = trueExpr; 27 | this.falseExpr = falseExpr; 28 | }; 29 | 30 | /** 31 | * Inherit from `Node.prototype`. 32 | */ 33 | 34 | Ternary.prototype.__proto__ = Node.prototype; 35 | 36 | /** 37 | * Return a clone of this node. 38 | * 39 | * @return {Node} 40 | * @api public 41 | */ 42 | 43 | Ternary.prototype.clone = function(){ 44 | var clone = new Ternary( 45 | this.cond.clone() 46 | , this.trueExpr.clone() 47 | , this.falseExpr.clone()); 48 | clone.lineno = this.lineno; 49 | clone.filename = this.filename; 50 | return clone; 51 | }; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2010 LearnBoost 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /test/cases/kwargs.css: -------------------------------------------------------------------------------- 1 | #login { 2 | padding-top: 15px; 3 | padding-bottom: 100px; 4 | } 5 | #login { 6 | padding-top: 15px; 7 | padding-bottom: 100px; 8 | } 9 | #login { 10 | padding-top: 15px; 11 | padding-bottom: 100px; 12 | } 13 | #login { 14 | padding-top: 15px; 15 | padding-bottom: 100px; 16 | } 17 | #login { 18 | padding-top: 15px; 19 | padding-bottom: 100px; 20 | } 21 | #login { 22 | padding-top: 15px; 23 | padding-bottom: 100px; 24 | } 25 | #login { 26 | padding-top: 15px; 27 | padding-bottom: 100px; 28 | } 29 | #login { 30 | padding-top: 15px; 31 | padding-bottom: 100px; 32 | } 33 | #login { 34 | foo: 0.2; 35 | foo: 5; 36 | foo: 5; 37 | foo: 5; 38 | foo: 5; 39 | foo: 5; 40 | foo: 5; 41 | foo: 5; 42 | foo: 0.2; 43 | foo: 0.2; 44 | } 45 | body { 46 | foo: "1, 2, 3"; 47 | foo: "1, 2, 3"; 48 | foo: "1, 2, 3"; 49 | foo: "1|2|3"; 50 | foo: "1|2|3"; 51 | } 52 | body { 53 | foo: "1|2|3"; 54 | foo: "1|2|3"; 55 | foo: "1|2|3"; 56 | } 57 | body { 58 | foo: rgba(100,50,10,0.50); 59 | foo: rgba(100,50,10,0.50); 60 | foo: rgba(100,50,10,0.50); 61 | foo: rgba(100,50,10,0.50); 62 | foo: rgba(100,50,10,0.50); 63 | } -------------------------------------------------------------------------------- /test/cases/css.mixins.styl: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Reset button related properties so that 4 | * a, button, and input's are supported. 5 | */ 6 | 7 | -reset() 8 | display: block; 9 | text-decoration: none; 10 | 11 | /* 12 | * Minimalistic flat button with white inset. 13 | */ 14 | 15 | minimal-button(bg = #e3e3e3, intensity = 1) 16 | -reset() 17 | background: bg; 18 | border: 1px solid darken(bg, 15 * intensity); 19 | border-radius: 3px; 20 | box-shadow: inset 0 0 1px 1px rgba(white, 0.8 * intensity); 21 | color: #333; 22 | font-family: 'helvetica neue', helvetica, arial, sans-serif; 23 | font-size: 12px; 24 | font-weight: bold; 25 | line-height: 1; 26 | padding: 8px 0 9px; 27 | text-align: center; 28 | text-shadow: 0 1px 0 rgba(white, 1 * intensity); 29 | width: 150px; 30 | 31 | &:hover { 32 | background: darken(bg, 3); 33 | box-shadow: inset 0 0 1px 1px rgba(white, 0.5 * intensity); 34 | color: #222; 35 | cursor: pointer; 36 | } 37 | 38 | &:active { 39 | background: darken(bg, 5); 40 | box-shadow: inset 0 0 1px 1px rgba(white, 0.2 * intensity); 41 | color: #000; 42 | } 43 | 44 | button, 45 | a.button { 46 | minimal-button(); 47 | } -------------------------------------------------------------------------------- /lib/nodes/each.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Each 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node') 13 | , nodes = require('./'); 14 | 15 | /** 16 | * Initialize a new `Each` node with the given `val` name, 17 | * `key` name, `expr`, and `block`. 18 | * 19 | * @param {String} val 20 | * @param {String} key 21 | * @param {Expression} expr 22 | * @param {Block} block 23 | * @api public 24 | */ 25 | 26 | var Each = module.exports = function Each(val, key, expr, block){ 27 | Node.call(this); 28 | this.val = val; 29 | this.key = key; 30 | this.expr = expr; 31 | this.block = block; 32 | }; 33 | 34 | /** 35 | * Inherit from `Node.prototype`. 36 | */ 37 | 38 | Each.prototype.__proto__ = Node.prototype; 39 | 40 | /** 41 | * Return a clone of this node. 42 | * 43 | * @return {Node} 44 | * @api public 45 | */ 46 | 47 | Each.prototype.clone = function(){ 48 | var clone = new Each( 49 | this.val 50 | , this.key 51 | , this.expr.clone() 52 | , this.block.clone()); 53 | clone.lineno = this.lineno; 54 | clone.filename = this.filename; 55 | return clone; 56 | }; -------------------------------------------------------------------------------- /lib/errors.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - errors 4 | * Copyright(c) 2010 LearnBoost 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 | 59 | -------------------------------------------------------------------------------- /lib/nodes/selector.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Selector 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Block = require('./block') 13 | , Node = require('./node'); 14 | 15 | /** 16 | * Initialize a new `Selector` with the given `segs`. 17 | * 18 | * @param {Array} segs 19 | * @api public 20 | */ 21 | 22 | var Selector = module.exports = function Selector(segs){ 23 | Node.call(this); 24 | this.segments = segs; 25 | }; 26 | 27 | /** 28 | * Inherit from `Node.prototype`. 29 | */ 30 | 31 | Selector.prototype.__proto__ = Node.prototype; 32 | 33 | /** 34 | * Return the selector string. 35 | * 36 | * @return {String} 37 | * @api public 38 | */ 39 | 40 | Selector.prototype.toString = function(){ 41 | return this.segments.join(''); 42 | }; 43 | 44 | /** 45 | * Return a clone of this node. 46 | * 47 | * @return {Node} 48 | * @api public 49 | */ 50 | 51 | Selector.prototype.clone = function(){ 52 | var clone = new Selector; 53 | clone.lineno = this.lineno; 54 | clone.filename = this.filename; 55 | clone.segments = this.segments.map(function(node){ return node.clone(); }); 56 | return clone; 57 | }; 58 | -------------------------------------------------------------------------------- /lib/nodes/if.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - If 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node'); 13 | 14 | /** 15 | * Initialize a new `If` with the given `cond`. 16 | * 17 | * @param {Expression} cond 18 | * @param {Boolean|Block} negate, block 19 | * @api public 20 | */ 21 | 22 | var If = module.exports = function If(cond, negate){ 23 | Node.call(this); 24 | this.cond = cond; 25 | this.elses = []; 26 | if (negate && negate.nodeName) { 27 | this.block = negate; 28 | } else { 29 | this.negate = negate; 30 | } 31 | }; 32 | 33 | /** 34 | * Inherit from `Node.prototype`. 35 | */ 36 | 37 | If.prototype.__proto__ = Node.prototype; 38 | 39 | /** 40 | * Return a clone of this node. 41 | * 42 | * @return {Node} 43 | * @api public 44 | */ 45 | 46 | If.prototype.clone = function(){ 47 | var cond = this.cond.clone() 48 | , block = this.block.clone(); 49 | var clone = new If(cond, block); 50 | clone.elses = this.elses.map(function(node){ return node.clone(); }); 51 | clone.negate = this.negate; 52 | clone.lineno = this.lineno; 53 | clone.filename = this.filename; 54 | return clone; 55 | }; 56 | -------------------------------------------------------------------------------- /test/cases/bifs.add-property.styl: -------------------------------------------------------------------------------- 1 | 2 | string(val) 3 | '' + val 4 | 5 | replace(expr, str, val) 6 | expr[i] = val if string(e) == str for e, i in expr 7 | 8 | linear-gradient(from, to) { 9 | if current-property { 10 | webkit = s('-webkit-gradient(linear, 0% 0%, 0% 100%, from(%s), to(%s))', from, to); 11 | moz = s('-moz-linear-gradient(%s, %s)', from, to); 12 | prop = current-property; 13 | replace(current-property[1], '__CALL__', moz); 14 | add-property(prop[0], prop[1]); 15 | webkit; 16 | } else { 17 | error('linear-gradient() must be used within a property'); 18 | } 19 | } 20 | 21 | body 22 | background foo linear-gradient(#2a2a2a, #454545) bar 23 | 24 | body 25 | background-image linear-gradient(#2a2a2a, #454545) 26 | 27 | body 28 | foo linear-gradient(#333, #999) 29 | 30 | mixin() 31 | foo linear-gradient(#eee, #999) 32 | 33 | body 34 | mixin() 35 | 36 | // multiple calls 37 | 38 | something(val) 39 | if current-property 40 | add-property(current-property[0], s('-webkit-something(%s)', val)) 41 | add-property(current-property[0], s('-moz-something(%s)', val)) 42 | s('something(%s)', val) 43 | else 44 | error('something() must be used within a property') 45 | 46 | body { 47 | foo: something(15px); 48 | } -------------------------------------------------------------------------------- /lib/nodes/null.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Null 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node') 13 | , nodes = require('./'); 14 | 15 | /** 16 | * Initialize a new `Null` node. 17 | * 18 | * @api public 19 | */ 20 | 21 | var Null = module.exports = function Null(){}; 22 | 23 | /** 24 | * Inherit from `Node.prototype`. 25 | */ 26 | 27 | Null.prototype.__proto__ = Node.prototype; 28 | 29 | /** 30 | * Return 'Null'. 31 | * 32 | * @return {String} 33 | * @api public 34 | */ 35 | 36 | Null.prototype.inspect = 37 | Null.prototype.toString = function(){ 38 | return 'null'; 39 | }; 40 | 41 | /** 42 | * Return false. 43 | * 44 | * @return {Boolean} 45 | * @api public 46 | */ 47 | 48 | Null.prototype.toBoolean = function(){ 49 | return nodes.false; 50 | }; 51 | 52 | /** 53 | * Check if the node is a null node. 54 | * 55 | * @return {Boolean} 56 | * @api public 57 | */ 58 | 59 | Null.prototype.__defineGetter__('isNull', function(){ 60 | return true; 61 | }); 62 | 63 | /** 64 | * Return hash. 65 | * 66 | * @return {String} 67 | * @api public 68 | */ 69 | 70 | Null.prototype.__defineGetter__('hash', function(){ 71 | return null; 72 | }); -------------------------------------------------------------------------------- /test/cases/css.mixins.braces.styl: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Reset button related properties so that 4 | * a, button, and input's are supported. 5 | */ 6 | 7 | -reset() { 8 | display: block; 9 | text-decoration: none; 10 | } 11 | 12 | // just testing stuff 13 | 14 | get-width() { 150px; } 15 | 16 | /* 17 | * Minimalistic flat button with white inset. 18 | */ 19 | 20 | minimal-button(bg = #e3e3e3, intensity = 1) { 21 | -reset(); 22 | background: bg; 23 | border: 1px solid darken(bg, 15 * intensity); 24 | border-radius: 3px; 25 | box-shadow: inset 0 0 1px 1px rgba(white, 0.8 * intensity); 26 | color: #333; 27 | font-family: 'helvetica neue', helvetica, arial, sans-serif; 28 | font-size: 12px; 29 | font-weight: bold; 30 | line-height: 1; 31 | padding: 8px 0 9px; 32 | text-align: center; 33 | text-shadow: 0 1px 0 rgba(white, 1 * intensity); 34 | width: get-width(); 35 | 36 | &:hover { 37 | background: darken(bg, 3); 38 | box-shadow: inset 0 0 1px 1px rgba(white, 0.5 * intensity); 39 | color: #222; 40 | cursor: pointer; 41 | } 42 | 43 | &:active { 44 | background: darken(bg, 5); 45 | box-shadow: inset 0 0 1px 1px rgba(white, 0.2 * intensity); 46 | color: #000; 47 | } 48 | } 49 | 50 | button, 51 | a.button { 52 | minimal-button(); 53 | } -------------------------------------------------------------------------------- /docs/gedit.md: -------------------------------------------------------------------------------- 1 | ## gedit language-spec 2 | 3 | Stylus ships with a temporary version of `styl.lang` for [GtkSourceView](http://live.gnome.org/GtkSourceView), based off [Yanekk](https://github.com/yanekk)'s [work](https://github.com/gmate/gmate/blob/master/lang-specs/scss.lang) on `scss.lang`. 4 | 5 | ![Stylus Language Specification for GtkSourceView](http://i.imgur.com/uBppL.png)) 6 | 7 | This is a start and provides a basic [language spec](http://live.gnome.org/Gedit/NewLanguage) for GtkSourceView editors such as [gedit](http://projects.gnome.org/gedit/). 8 | 9 | **Installation Steps** 10 | 11 | Download `styl.lang` to your local `language-specs` folder: 12 | 13 | mkdir -p ~/.local/share/gtksourceview-2.0/language-specs/ && wget https://raw.github.com/LearnBoost/stylus/master/editors/gedit/styl.lang -O ~/.local/share/gtksourceview-2.0/language-specs/styl.lang 14 | 15 | Update the mime database and enjoy Stylus syntax in gedit! 16 | 17 | cd ~/.local/share 18 | update-mime-database mime 19 | 20 | This is much more enjoyable than having gedit recognize your `.styl` files as Apache Confs! 21 | 22 | --- 23 | 24 | **Have a sweet tooth?** Add more icing to gedit with gedit-icing: [https://github.com/niftylettuce/gedit-icing](https://github.com/niftylettuce/gedit-icing) 25 | -------------------------------------------------------------------------------- /test/cases/functions.return.styl: -------------------------------------------------------------------------------- 1 | 2 | large(n) 3 | unless n is a 'unit' 4 | return false 5 | if n > 100 6 | yes 7 | else 8 | no 9 | 10 | awesome() 11 | yes 12 | 13 | nested(a = 5) 14 | if a is a 'unit' 15 | b = 10 16 | if a 17 | c = 100 18 | c = 100 19 | c = 100 20 | c = 100 21 | awesome() 22 | else 23 | 'b is not a unit' 24 | else 25 | 'a is not a unit' 26 | 27 | set() 28 | 1 29 | return 2 30 | 3 31 | 32 | body 33 | // no 34 | foo large(15) 35 | 36 | // yes 37 | foo large(150) 38 | 39 | // false 40 | foo large('string') 41 | 42 | // yes 43 | foo nested() 44 | 45 | // 'a is not a unit' 46 | foo nested('wahoo') 47 | 48 | // 2 49 | foo set() 50 | 51 | deep-implicit() 52 | one 53 | if false 54 | two 55 | else 56 | if true 57 | something 58 | three 59 | else 60 | four 61 | five 62 | 63 | deep-explicit() 64 | one 65 | if false 66 | two 67 | else 68 | if true 69 | return something 70 | three 71 | else 72 | four 73 | five 74 | 75 | body 76 | foo deep-implicit() 77 | foo deep-explicit() 78 | 79 | test() 80 | return 1 if false 81 | return 2 if false 82 | return 3 if true 83 | return 4 84 | 85 | body 86 | foo test() -------------------------------------------------------------------------------- /lib/stack/frame.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - stack - Frame 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Scope = require('./scope') 13 | , blocks = require('../nodes'); 14 | 15 | /** 16 | * Initialize a new `Frame` with the given `block`. 17 | * 18 | * @param {Block} block 19 | * @api private 20 | */ 21 | 22 | var Frame = module.exports = function Frame(block) { 23 | this._scope = false === block.scope 24 | ? null 25 | : new Scope; 26 | this.block = block; 27 | }; 28 | 29 | /** 30 | * Return this frame's scope or the parent scope 31 | * for scope-less blocks. 32 | * 33 | * @return {Scope} 34 | * @api public 35 | */ 36 | 37 | Frame.prototype.__defineGetter__('scope', function(){ 38 | return this._scope || this.parent.scope; 39 | }); 40 | 41 | /** 42 | * Lookup the given local variable `name`. 43 | * 44 | * @param {String} name 45 | * @return {Node} 46 | * @api private 47 | */ 48 | 49 | Frame.prototype.lookup = function(name){ 50 | return this.scope.lookup(name) 51 | }; 52 | 53 | /** 54 | * Custom inspect. 55 | * 56 | * @return {String} 57 | * @api public 58 | */ 59 | 60 | Frame.prototype.inspect = function(){ 61 | return '[Frame ' 62 | + (false === this.block.scope 63 | ? 'scope-less' 64 | : this.scope.inspect()) 65 | + ']'; 66 | }; 67 | -------------------------------------------------------------------------------- /test/cases/if.styl: -------------------------------------------------------------------------------- 1 | n = false 2 | 3 | if !n 4 | n = 100 5 | 6 | body 7 | padding n 8 | 9 | n = false 10 | 11 | if not not n 12 | n = 50 13 | 14 | body 15 | padding n 16 | 17 | if not n 18 | n = 150 19 | 20 | body 21 | padding n 22 | 23 | if n 24 | n = n / 2 25 | else 26 | n = 10000 27 | 28 | body 29 | padding n 30 | 31 | if n > 100 32 | n = n * 2 33 | else 34 | n = -1 35 | 36 | body 37 | padding n 38 | 39 | n = 75 40 | 41 | if n < 50 42 | n = n 43 | else 44 | if n > 50 and n < 100 45 | n = 1 46 | else 47 | n = -1 48 | 49 | body 50 | padding n 51 | 52 | negative(n) 53 | unless n is a 'unit' 54 | return invalid 55 | if n < 0 56 | yes 57 | else if n > 0 58 | no 59 | else 60 | zero 61 | 62 | body 63 | foo negative(-5) 64 | foo negative(5) 65 | foo negative(0) 66 | foo negative('asdf') 67 | 68 | body 69 | .input 70 | pad = true 71 | margin = false 72 | if pad 73 | padding 5px 74 | if margin 75 | margin 5px 76 | else 77 | no unquote('margin') 78 | 79 | mixin() 80 | foo bar 81 | bar baz 82 | 83 | body 84 | form input 85 | if true 86 | foo negative(5) 87 | mixin() 88 | something 89 | mixin() 90 | 91 | body 92 | .nested 93 | if true 94 | if true 95 | if true 96 | foo bar 97 | .hidden 98 | if true 99 | display none -------------------------------------------------------------------------------- /lib/nodes/arguments.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Arguments 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node') 13 | , nodes = require('../nodes') 14 | , utils = require('../utils'); 15 | 16 | /** 17 | * Initialize a new `Arguments`. 18 | * 19 | * @api public 20 | */ 21 | 22 | var Arguments = module.exports = function Arguments(){ 23 | nodes.Expression.call(this); 24 | this.map = {}; 25 | }; 26 | 27 | /** 28 | * Inherit from `nodes.Expression.prototype`. 29 | */ 30 | 31 | Arguments.prototype.__proto__ = nodes.Expression.prototype; 32 | 33 | /** 34 | * Initialize an `Arguments` object with the nodes 35 | * from the given `expr`. 36 | * 37 | * @param {Expression} expr 38 | * @return {Arguments} 39 | * @api public 40 | */ 41 | 42 | Arguments.fromExpression = function(expr){ 43 | var args = new Arguments 44 | , len = expr.nodes.length; 45 | args.lineno = expr.lineno; 46 | args.isList = expr.isList; 47 | for (var i = 0; i < len; ++i) { 48 | args.push(expr.nodes[i]); 49 | } 50 | return args; 51 | }; 52 | 53 | /** 54 | * Return a clone of this node. 55 | * 56 | * @return {Node} 57 | * @api public 58 | */ 59 | 60 | Arguments.prototype.clone = function(){ 61 | var clone = nodes.Expression.prototype.clone.call(this); 62 | clone.map = this.map; 63 | return clone; 64 | }; 65 | 66 | -------------------------------------------------------------------------------- /test/cases/css.selector.interpolation.css: -------------------------------------------------------------------------------- 1 | form input:last-child { 2 | display: none; 3 | } 4 | form input:nth-child(15) { 5 | display: none; 6 | } 7 | .grid-1 { 8 | width: 100px; 9 | } 10 | .grid-2 { 11 | width: 200px; 12 | } 13 | .grid-3 { 14 | width: 300px; 15 | } 16 | .grid-4 { 17 | width: 400px; 18 | } 19 | .grid-5 { 20 | width: 500px; 21 | } 22 | body form input:last-child { 23 | display: none; 24 | } 25 | ul li:nth-child(2) { 26 | display: none; 27 | } 28 | foo bar { 29 | foo: bar; 30 | } 31 | foo bar baz { 32 | foo: bar; 33 | } 34 | foo { 35 | two: 2; 36 | } 37 | foo bar { 38 | one: 1; 39 | } 40 | foo bar baz { 41 | foo: bar; 42 | } 43 | one * { 44 | one: 1; 45 | two: 2; 46 | three: 3; 47 | } 48 | two * { 49 | one: 1; 50 | two: 2; 51 | three: 3; 52 | } 53 | three * { 54 | one: 1; 55 | two: 2; 56 | three: 3; 57 | } 58 | li a:active { 59 | color: #000; 60 | background: #fff; 61 | } 62 | li a:active { 63 | color: #000; 64 | background: #fff; 65 | } 66 | .col-1-0 :nth-child(1) { 67 | foo: "bar"; 68 | } 69 | .col-1 { 70 | foo: "bar"; 71 | } 72 | .col-2 { 73 | foo: "bar"; 74 | } 75 | .col-3 { 76 | foo: "bar"; 77 | } 78 | @media print { 79 | blockquote { 80 | border: 1px solid #999; 81 | } 82 | blockquote { 83 | border: 1px solid #999; 84 | } 85 | blockquote { 86 | border: 1px solid #999; 87 | } 88 | blockquote { 89 | border: 1px solid #999; 90 | } 91 | } -------------------------------------------------------------------------------- /lib/nodes/params.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Stylus - Params 4 | * Copyright(c) 2010 LearnBoost 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var Node = require('./node'); 13 | 14 | /** 15 | * Initialize a new `Params` with `name`, `params`, and `body`. 16 | * 17 | * @param {String} name 18 | * @param {Params} params 19 | * @param {Expression} body 20 | * @api public 21 | */ 22 | 23 | var Params = module.exports = function Params(){ 24 | Node.call(this); 25 | this.nodes = []; 26 | }; 27 | 28 | /** 29 | * Check function arity. 30 | * 31 | * @return {Boolean} 32 | * @api public 33 | */ 34 | 35 | Params.prototype.__defineGetter__('length', function(){ 36 | return this.nodes.length; 37 | }); 38 | 39 | /** 40 | * Inherit from `Node.prototype`. 41 | */ 42 | 43 | Params.prototype.__proto__ = Node.prototype; 44 | 45 | /** 46 | * Push the given `node`. 47 | * 48 | * @param {Node} node 49 | * @api public 50 | */ 51 | 52 | Params.prototype.push = function(node){ 53 | this.nodes.push(node); 54 | }; 55 | 56 | /** 57 | * Return a clone of this node. 58 | * 59 | * @return {Node} 60 | * @api public 61 | */ 62 | 63 | Params.prototype.clone = function(){ 64 | var clone = new Params; 65 | clone.lineno = this.lineno; 66 | clone.filename = this.filename; 67 | this.nodes.forEach(function(node){ 68 | clone.push(node.clone()); 69 | }); 70 | return clone; 71 | }; 72 | 73 | -------------------------------------------------------------------------------- /test/cases/operators.subscript.styl: -------------------------------------------------------------------------------- 1 | body 2 | foo ()[0] == null 3 | foo (1(2(3 4 5)))[1][1] 4 | foo (1 2 3)['test'] == null 5 | foo !(1 0)[1] 6 | foo !(1 0)[0] 7 | foo - - -(1 2 3 4 5)[4] 8 | 9 | body 10 | foo (1 (2 (3 4))) 11 | foo (1 (2 (3 4)))[0] 12 | foo (1 (2 (3 4)))[1] 13 | foo (1 (2 (3 4)))[1][0] 14 | foo (1 (2 (3 4)))[1][1] 15 | foo (1 (2 (3 4)))[1][1][0] 16 | foo (1 (2 (3 4)))[1][1][1] 17 | foo (1 (2 (3 4)))[1][1][3] 18 | 19 | body 20 | foo (error 'message')[0] 21 | foo (error 'message')[1] 22 | 23 | size(a, b) 24 | return a b 25 | 26 | body 27 | foo size(5, 10)[0] 28 | foo size(5, 10)[1] 29 | 30 | size(a, b) 31 | (a b) 32 | 33 | body 34 | foo size(5, 10)[0] 35 | foo size(5, 10)[1] 36 | 37 | size() 38 | (1 2) (3 4) 39 | 40 | body 41 | foo size()[0] 42 | foo size()[1] 43 | foo size()[1][1] 44 | 45 | image-size(path) 46 | w = 100 47 | h = 200 48 | return w h 49 | 50 | body 51 | size = image-size('test.png') 52 | foo size 53 | foo size[0] 54 | foo size[1] 55 | foo length(size) 56 | 57 | image-size(path) 58 | 100 200 59 | 60 | body 61 | size = image-size('test.png') 62 | foo size 63 | foo size[0] 64 | foo size[1] 65 | foo length(size) 66 | 67 | size = 100 200 68 | 69 | body 70 | foo size 71 | foo size[0] 72 | foo size[1] 73 | foo length(size) 74 | 75 | size = (100 200) 76 | 77 | body 78 | foo size 79 | foo size[0] 80 | foo size[1] 81 | foo length(size) 82 | -------------------------------------------------------------------------------- /examples/js-functions.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var css = require('../') 7 | , nodes = css.nodes 8 | , str = require('fs').readFileSync(__dirname + '/js-functions.styl', 'utf8') 9 | , fs = require('fs'); 10 | 11 | function add(a, b) { 12 | return a.operate('+', b); 13 | } 14 | 15 | function sub(a, b) { 16 | return a.operate('-', b); 17 | } 18 | 19 | function imageSize(img) { 20 | // assert that the node (img) is a String node, passing 21 | // the param name for error reporting 22 | css.utils.assertType(img, 'string', 'img'); 23 | var path = img.val; 24 | 25 | // Grab bytes necessary to retrieve dimensions. 26 | // if this was real you would do this per format, 27 | // instead of reading the entire image :) 28 | var data = fs.readFileSync(__dirname + '/' + path); 29 | 30 | // GIF 31 | // of course you would support.. more :) 32 | if ('GIF' == data.slice(0, 3).toString()) { 33 | var w = data.slice(6, 8) 34 | , h = data.slice(8, 10); 35 | w = w[1] << 8 | w[0]; 36 | h = h[1] << 8 | h[0]; 37 | } 38 | 39 | // Return (w h) 40 | var expr = new nodes.Expression; 41 | expr.push(new nodes.Unit(w)); 42 | expr.push(new nodes.Unit(h)); 43 | 44 | return expr; 45 | } 46 | 47 | css(str) 48 | .set('filename', 'js-functions.styl') 49 | .define('add', add) 50 | .define('sub', sub) 51 | .define('image-size', imageSize) 52 | .render(function(err, css){ 53 | if (err) throw err; 54 | console.log(css); 55 | }); -------------------------------------------------------------------------------- /docs/error-reporting.md: -------------------------------------------------------------------------------- 1 | 2 | ## Error Reporting 3 | 4 | Stylus has fantastic error reporting built in for syntax, parse, and evaluation errors, complete with stack traces, line numbers, and filenames. 5 | 6 | ### Parse Error 7 | 8 | Parse error example: 9 | 10 | body 11 | form input 12 | == padding 5px 13 | 14 | yielding: 15 | 16 | Error: /Users/tj/Projects/stylus/testing/test.styl:4 17 | 3: ' form input' 18 | 4: ' == padding 5px' 19 | 20 | illegal unary == 21 | 22 | ### Evaluation Error 23 | 24 | This "runtime" or evaluation error is caused due to passing a string to `border-radius()` instead of the expected `Unit` by using our helper `ensure(n, 'unit')`. 25 | 26 | ensure(val, type) 27 | unless val is a type 28 | error('expected a ' + type + ', but got ' + typeof(val)) 29 | 30 | border-radius(n) 31 | ensure(n, 'unit') 32 | -webkit-border-radius n 33 | -moz-border-radius n 34 | border-radius n 35 | 36 | body 37 | border-radius '5px' 38 | 39 | yielding: 40 | 41 | Error: /Users/tj/Projects/stylus/examples/error.styl:12 42 | 11: '' 43 | 12: 'body' 44 | 13: ' border-radius \'5px\'' 45 | 14: '' 46 | 47 | expected a unit, but got string 48 | at ensure() (/Users/tj/Projects/stylus/examples/error.styl:2) 49 | at border-radius() (/Users/tj/Projects/stylus/examples/error.styl:5) 50 | at "body" (/Users/tj/Projects/stylus/examples/error.styl:10) 51 | -------------------------------------------------------------------------------- /test/cases/css.selector.interpolation.styl: -------------------------------------------------------------------------------- 1 | form {'input'}:last-child { 2 | display: none; 3 | } 4 | 5 | form {'input'}:nth-child({10 + 5}) { 6 | display: none; 7 | } 8 | 9 | for n in 1 2 3 4 5 { 10 | .grid-{n} { 11 | width: unit(n * 100, 'px'); 12 | } 13 | } 14 | 15 | pos = last 16 | 17 | body {form} { 18 | input:{ pos }-child { 19 | display: none 20 | } 21 | } 22 | 23 | mixin(n) { 24 | &:nth-child({ n }) { 25 | display: none 26 | } 27 | } 28 | 29 | ul li { 30 | mixin(2); 31 | } 32 | 33 | {foo} {bar} { 34 | foo: bar; 35 | } 36 | 37 | {foo} { 38 | {bar} { 39 | {baz} { 40 | foo: bar; 41 | } 42 | } 43 | } 44 | 45 | {foo} { 46 | {bar} { 47 | {baz} { 48 | {foo}: bar 49 | } 50 | {one} 1 51 | } 52 | {two} 2 53 | } 54 | 55 | selectors = one two three; 56 | props = (one 1) (two 2) (three 3); 57 | 58 | for selector in selectors { 59 | {selector} * { 60 | for prop in props { 61 | {prop[0]}: prop[1]; 62 | } 63 | } 64 | } 65 | 66 | 67 | li a:active { color: black; background: white; } 68 | 69 | state = 'active' 70 | li a:{state} { color: black; background: white; } 71 | 72 | .col-{1}-{0} :nth-child(1) { foo: 'bar'; } 73 | 74 | cols = 1 2 3 75 | 76 | for col in cols 77 | .col-{col} { foo: 'bar'; } 78 | 79 | 80 | @media print { 81 | blockquote { border: 1px solid #999 } 82 | blockquote { 83 | border: 1px solid #999 84 | } 85 | block{'quote'} { border: 1px solid #999 } 86 | block{'quote'} { 87 | border: 1px solid #999 88 | } 89 | } 90 | 91 | -------------------------------------------------------------------------------- /docs/interpolation.md: -------------------------------------------------------------------------------- 1 | 2 | ## Interpolation 3 | 4 | Stylus supports interpolation by using the `{}` characters to surround an expression, which then becomes part of the identifier. For example `-webkit-{'border' + '-radius'}` would evaluate to `-webkit-border-radius`. 5 | 6 | A great example use-case for this is expanding properties with vendor prefixes. 7 | 8 | vendor(prop, args) 9 | -webkit-{prop} args 10 | -moz-{prop} args 11 | {prop} args 12 | 13 | border-radius() 14 | vendor('border-radius', arguments) 15 | 16 | box-shadow() 17 | vendor('box-shadow', arguments) 18 | 19 | button 20 | border-radius 1px 2px / 3px 4px 21 | 22 | yielding: 23 | 24 | button { 25 | -webkit-border-radius: 1px 2px / 3px 4px; 26 | -moz-border-radius: 1px 2px / 3px 4px; 27 | border-radius: 1px 2px / 3px 4px; 28 | } 29 | 30 | ## Selector Interpolation 31 | 32 | Interpolation works with selectors as well, for example we may iterate while assigning the `height` property for the first 5 rows in a table as shown below. 33 | 34 | table 35 | for row in 1 2 3 4 5 36 | tr:nth-child({row}) 37 | height: 10px * row 38 | 39 | yielding: 40 | 41 | table tr:nth-child(1) { 42 | height: 10px; 43 | } 44 | table tr:nth-child(2) { 45 | height: 20px; 46 | } 47 | table tr:nth-child(3) { 48 | height: 30px; 49 | } 50 | table tr:nth-child(4) { 51 | height: 40px; 52 | } 53 | table tr:nth-child(5) { 54 | height: 50px; 55 | } -------------------------------------------------------------------------------- /test/cases/kwargs.styl: -------------------------------------------------------------------------------- 1 | pad-y(top, bottom) { 2 | padding-top: top; 3 | padding-bottom: bottom; 4 | } 5 | 6 | #login { 7 | pad-y(15px, 100px); 8 | } 9 | 10 | #login { 11 | pad-y(bottom: 100px, top: 15px); 12 | } 13 | 14 | #login { 15 | pad-y(top: 15px, bottom: 100px); 16 | } 17 | 18 | #login { 19 | pad-y(bottom: 100px, 15px); 20 | } 21 | 22 | #login { 23 | pad-y(15px, bottom: 100px); 24 | } 25 | 26 | #login { 27 | pad-y(100px, top: 15px); 28 | } 29 | 30 | #login { 31 | pad-y(top: 15px, 100px); 32 | } 33 | 34 | #login { 35 | pad-y(15px, bottom: 100px); 36 | } 37 | 38 | #login { 39 | foo: operate('/', 2, 10); 40 | foo: operate('/', 10, 2); 41 | 42 | foo: operate(op: '/', 10, 2); 43 | foo: operate(10, op: '/', 2); 44 | foo: operate(10, 2, op: '/'); 45 | 46 | foo: operate('/', left: 10, right: 2); 47 | foo: operate('/', right: 2, left: 10); 48 | foo: operate(right: 2, left: 10, op: '/'); 49 | 50 | foo: operate(right: 10, left: 2, op: '/'); 51 | foo: operate('/', left: 2, right: 10); 52 | } 53 | 54 | body { 55 | foo: join(', ', 1, 2, 3); 56 | foo: join(', ', 1 2 3); 57 | foo: join(delim: ', ', 1, 2, 3); 58 | foo: join(1, 2, 3, delim: '|'); 59 | foo: join(1, delim: '|', 2, 3); 60 | } 61 | 62 | body { 63 | foo: join('|', 1, 2, 3); 64 | foo: join(1 2 3, delim: '|'); 65 | foo: join(delim: '|', 1 2 3); 66 | } 67 | 68 | body { 69 | foo: rgba(100,50,10,0.5); 70 | foo: rgba(100,alpha: 0.5, 50,10); 71 | foo: rgba(alpha: 0.5, 100, 50,10); 72 | foo: rgba(alpha: 0.5, green: 50, red: 100, 10); 73 | foo: rgba(alpha: 0.5, green: 50, red: 100, blue: 10); 74 | } -------------------------------------------------------------------------------- /docs/compare.md: -------------------------------------------------------------------------------- 1 | ## Implementation Comparisons 2 | 3 | Below we go head to head with other implementations. 4 | 5 | ### Variables 6 | 7 | SCSS: 8 | 9 | $main-color: #006; 10 | color: $main-color; 11 | 12 | Less: 13 | 14 | @main-color: #006; 15 | color: @main-color; 16 | 17 | Stylus: 18 | 19 | main-color = #006 20 | color main-color 21 | 22 | ### Mixins 23 | 24 | SCSS: 25 | 26 | @mixin pad($x, $y) { 27 | padding: $y $x; 28 | } 29 | 30 | .msg { 31 | @include pad(5px, 10px); 32 | } 33 | 34 | Less: 35 | 36 | .pad(@x, @y) { 37 | padding: @y @x; 38 | } 39 | 40 | .msg { 41 | .pad(5px, 10px); 42 | } 43 | 44 | Stylus: 45 | 46 | pad(x, y) 47 | padding y x 48 | 49 | .msg 50 | pad(5px, 10px) 51 | 52 | ### Larger Example 53 | 54 | Less: 55 | 56 | .box-shadow (@x: 0, @y: 0, @blur: 1px, @alpha) { 57 | @val: @x @y @blur rgba(0, 0, 0, @alpha); 58 | box-shadow: @val; 59 | -webkit-box-shadow: @val; 60 | -moz-box-shadow: @val; 61 | } 62 | .box { 63 | @base: #f938ab; 64 | color: saturate(@base, 5%); 65 | border-color: lighten(@base, 30%); 66 | div { .box-shadow(0, 0, 5px, 0.4) } 67 | } 68 | 69 | Stylus: 70 | 71 | box-shadow() 72 | -webkit-box-shadow arguments 73 | -moz-box-shadow arguments 74 | box-shadow arguments 75 | 76 | .box 77 | base = #f938ab 78 | color saturate(base, 5%) 79 | border-color lighten(base, 30%) 80 | div 81 | box-shadow 0 0 5px 0.4 -------------------------------------------------------------------------------- /docs/functions.url.md: -------------------------------------------------------------------------------- 1 | ## Data URI Image Inlining 2 | 3 | Stylus is bundled with an optional function named `url()`, which replaces the literal `url()` calls, and conditionally inlines them using base64 [Data URIs](http://en.wikipedia.org/wiki/Data_URI_scheme). 4 | 5 | ### Example 6 | 7 | The function itself is available via `require('stylus').url`, and accepts an options object, returning a function that Stylus calls internally when it sees `url()`. 8 | 9 | The `.define(name, callback)` method assigned a JavaScript function that can be called from stylus source. In this case we have our images in `./css/images` then we can ignore the `paths` option, since image lookups are performed relative to the file being rendered (by default), we may alter this with the option. 10 | 11 | stylus(str) 12 | .set('filename', __dirname + '/css/test.styl') 13 | .define('url', stylus.url()) 14 | .render(function(err, css){ 15 | 16 | }); 17 | 18 | For example if our images live in `./public/images` and we wish to use `url(images/tobi.png)`, we can pass `paths` with our public directory, which will become part of the lookup process. Like-wise if we wanted `url(tobi.png)` instead, we would pass `paths: [__dirname + '/public/images']`. 19 | 20 | stylus(str) 21 | .set('filename', __dirname + '/css/test.styl') 22 | .define('url', stylus.url({ paths: [__dirname + '/public'] })) 23 | .render(function(err, css){ 24 | 25 | }); 26 | 27 | ### Options 28 | 29 | - `limit` bytesize limit defaulting to 30Kb (30000) 30 | - `paths` image resolution path(s) -------------------------------------------------------------------------------- /test/cases/operators.precedence.styl: -------------------------------------------------------------------------------- 1 | body 2 | // 4 3 | foo (--- 0) or 4 4 | // 4 5 | foo --- 0 or 4 6 | // -5px 7 | foo ---5px 8 | // 2 9 | foo (!!!5) or 2 10 | foo !!!5 or 2 11 | 12 | 13 | body 14 | // true 15 | foo !(! 5) 16 | foo !!5 17 | 18 | body 19 | // 5 20 | foo (! false) and (! false) and 5 21 | foo ! false and ! false and 5 22 | 23 | body 24 | // true 25 | foo (!!5 == true) or (!!0 == false) 26 | foo !!5 == true or !!0 == false 27 | foo (!!5 == false) or (!!0 == false) 28 | foo !!5 == false or !!0 == false 29 | // 2 30 | foo 5 < 10 and !!5 and 2 31 | 32 | body 33 | // true 34 | foo (!!true) and (!!true) 35 | foo !!true and !!true 36 | 37 | body 38 | test() 39 | 5 * 2 - 15 / 2 40 | // 2.5 41 | foo test() 42 | foo (5 * 2) - (15 / 2) 43 | 44 | body 45 | // true 46 | foo not 5 < 10 ? 0 : 1 47 | // true 48 | foo !(5 < 10 ? 0 : 1) 49 | // false 50 | foo !(5 > 10 ? 0 : 1) 51 | // wahoo 52 | foo !! 1 ? wahoo : fail 53 | // fail 54 | foo !1 ? wahoo : fail 55 | 56 | body 57 | foo = 'test' 58 | bar = 'test' 59 | // true 60 | foo (foo is defined) and (bar is defined) 61 | foo foo is defined and bar is defined 62 | 63 | body 64 | // true 65 | foo 5 > 4 is a 'boolean' 66 | 67 | foo = type is a 'unit' ? type : 1 68 | // 1 69 | foo foo 70 | 71 | body 72 | padding = false 73 | margin = false 74 | 75 | // true 76 | foo !padding or !margin 77 | foo not padding or margin 78 | 79 | // false 80 | foo not padding or margin == !padding or !margin 81 | // true 82 | foo (not padding or margin) == !padding or !margin 83 | --------------------------------------------------------------------------------