JavaScript API
Simply require
the module, and call render()
with the given string of Stylus code, and (optional) options
object.
Frameworks utilizing Stylus should pass the filename
option to provide better error reporting.
var stylus = require('stylus');
stylus.render(str, { filename: 'nesting.css' }, function(err, css){
if (err) throw err;
console.log(css);
});
We can also do the same thing in a more progressive manner:
var stylus = require('stylus');
stylus(str)
.set('filename', 'nesting.css')
.render(function(err, css){
// logic
});
.set(setting, value)
Apply a setting such as a filename
, or import paths
:
.set('filename', __dirname + '/test.styl')
.set('paths', [__dirname, __dirname + '/mixins'])
.include(path)
A progressive alternative to .set('paths',...)
is .include()
. This is ideal when exposing external Stylus libraries which expose a path.
stylus(str)
.include(require('nib').path)
.include(process.env.HOME + '/mixins')
.render(...)
.import(path)
Defer importing of the given path
until evaluation is performed. The example below is essentially the same as doing @import 'mixins/vendor'
within your Stylus sheet.
var stylus = require('../')
, str = require('fs').readFileSync(__dirname + '/test.styl', 'utf8');
stylus(str)
.set('filename', __dirname + '/test.styl')
.import('mixins/vendor')
.render(function(err, css){
if (err) throw err;
console.log(css);
});
.define(name, node)
By passing a Node
, we may define a global variable. This is useful when exposing conditional features within your library depending on the availability of another. For example the Nib extension library conditionally supports node-canvas, providing image generation.
However, this is not always available, so Nib may define:
.define('has-canvas', stylus.nodes.false);
.define('some-setting', new stylus.nodes.String('some value'));
Stylus also casts JavaScript values to their Stylus equivalents when possible. Here are a few examples:
.define('string', 'some string')
.define('number', 15.5)
.define('some-bool', true)
.define('list', [1,2,3])
.define('list', [1,2,[3,4,[5,6]]])
.define('list', { foo: 'bar', bar: 'baz' })
.define('families', ['Helvetica Neue', 'Helvetica', 'sans-serif'])
These same rules apply to return values in js functions as well:
.define('get-list', function(){
return ['foo', 'bar', 'baz'];
})
.define(name, fn)
This method allows you to provide a JavaScript-defined function to Stylus. Think of these as you would JavaScript-to-C++ bindings. When there’s something you cannot do in Stylus, define it in JavaScript!
In this example, we define four functions: add()
, sub()
, image-width()
, and image-height()
. These functions must return a Node
, this constructor and the other nodes are available via stylus.nodes
.
var stylus = require('../')
, nodes = stylus.nodes
, utils = stylus.utils
, fs = require('fs');
function add(a, b) {
return a.operate('+', b);
}
function sub(a, b) {
return a.operate('-', b);
}
function imageDimensions(img) {
// assert that the node (img) is a String node, passing
// the param name for error reporting
utils.assertType(img, 'string', 'img');
var path = img.val;
// Grab bytes necessary to retrieve dimensions.
// if this was real you would do this per format,
// instead of reading the entire image :)
var data = fs.readFileSync(__dirname + '/' + path);
// GIF
// of course you would support.. more :)
if ('GIF' == data.slice(0, 3).toString()) {
var w = data.slice(6, 8)
, h = data.slice(8, 10);
w = w[1] << 8 | w[0];
h = h[1] << 8 | h[0];
}
return [w, h];
}
function imageWidth(img) {
return new nodes.Unit(imageDimensions(img)[0]);
}
function imageHeight(img) {
return new nodes.Unit(imageDimensions(img)[1]);
}
stylus(str)
.set('filename', 'js-functions.styl')
.define('add', add)
.define('sub', sub)
.define('image-width', imageWidth)
.define('image-height', imageHeight)
.render(function(err, css){
if (err) throw err;
console.log(css);
});
For further reference (until documentation is complete) please see the following files:
lib/nodes/*
lib/utils.js
.use(fn)
When called, the given fn
is invoked with the renderer, allowing all of the methods above to be used. This allows for plugins to easily expose themselves, defining functions, paths etc.
var mylib = function(style){
style.define('add', add);
style.define('sub', sub);
};
stylus(str)
.use(mylib)
.render(...)
When calling the render()
method with options, the use
option can be given
a function or array of functions to be invoked with the renderer.
stylus.render(str, { use: mylib }, function(err, css){
if (err) throw err;
console.log(css);
});
.deps()
Returns array of dependencies (import files):
stylus('@import "a"; @import "b"')
.deps();
// => ['a.styl', 'b.styl']
See also –deps CLI flag.
stylus.resolver([options])
Optional built-in function which may be used to resolve relative urls inside imported files:
stylus(str)
.define('url', stylus.resolver())
.render(function(err, css) {
});
See also –resolve-url CLI flag.
Options:
paths
additional resolution path(s)nocheck
don’t check file existence