Commit 475c88e8 by Simon Wade

Added renderFile function

parent 4180123c
...@@ -78,6 +78,25 @@ The `map` option will create the source map file in your CSS destination. ...@@ -78,6 +78,25 @@ The `map` option will create the source map file in your CSS destination.
If your `sourceComments` option is set to `map`, `sourceMap` allows setting a new path context for the referenced Sass files. If your `sourceComments` option is set to `map`, `sourceMap` allows setting a new path context for the referenced Sass files.
The source map describes a path from your CSS file location, into the the folder where the Sass files are located. In most occasions this will work out-of-the-box but, in some cases, you may need to set a different output. The source map describes a path from your CSS file location, into the the folder where the Sass files are located. In most occasions this will work out-of-the-box but, in some cases, you may need to set a different output.
### renderFile()
Same as `render()` but writes the CSS and sourceMap (if requested) to the filesystem.
#### outFile
`outFile` specifies where to save the CSS.
#### sourceMap
`sourceMap` specifies that the source map should be saved.
- If falsy the source map will not be saved
- If `sourceMap === true` the source map will be saved to the
standard location of `path.basename(options.outFile) + '.map'`
- Otherwise specifies the path (relative to the `outFile`)
where the source map should be saved
### Examples ### Examples
```javascript ```javascript
......
...@@ -41,11 +41,11 @@ ...@@ -41,11 +41,11 @@
"mkdirp": "0.3.x", "mkdirp": "0.3.x",
"optimist": "0.6.x", "optimist": "0.6.x",
"node-watch": "0.3.x", "node-watch": "0.3.x",
"mocha": "1.18.x",
"chalk": "~0.4.0", "chalk": "~0.4.0",
"nan": "~0.8.0" "nan": "~0.8.0"
}, },
"devDependencies": { "devDependencies": {
"mocha": "1.18.x",
"jshint": "~2.4.4", "jshint": "~2.4.4",
"coveralls": "~2.10.0", "coveralls": "~2.10.0",
"mocha-lcov-reporter": "0.0.1", "mocha-lcov-reporter": "0.0.1",
......
...@@ -36,10 +36,14 @@ var SASS_SOURCE_COMMENTS = { ...@@ -36,10 +36,14 @@ var SASS_SOURCE_COMMENTS = {
var prepareOptions = function(options) { var prepareOptions = function(options) {
var paths, imagePath, style, comments; var paths, imagePath, style, comments;
options = typeof options !== 'object' ? {} : options; options = typeof options !== 'object' ? {} : options;
var sourceComments = options.source_comments || options.sourceComments;
if (options.sourceMap && !sourceComments) {
sourceComments = 'map';
}
paths = options.include_paths || options.includePaths || []; paths = options.include_paths || options.includePaths || [];
imagePath = options.image_path || options.imagePath || ''; imagePath = options.image_path || options.imagePath || '';
style = SASS_OUTPUT_STYLE[options.output_style || options.outputStyle] || 0; style = SASS_OUTPUT_STYLE[options.output_style || options.outputStyle] || 0;
comments = SASS_SOURCE_COMMENTS[options.source_comments || options.sourceComments] || 0; comments = SASS_SOURCE_COMMENTS[sourceComments] || 0;
return { return {
paths: paths, paths: paths,
...@@ -100,4 +104,59 @@ exports.renderSync = function(options) { ...@@ -100,4 +104,59 @@ exports.renderSync = function(options) {
return binding.renderSync(options.data, newOptions.imagePath, newOptions.paths.join(path.delimiter), newOptions.style); return binding.renderSync(options.data, newOptions.imagePath, newOptions.paths.join(path.delimiter), newOptions.style);
}; };
/**
Same as `render()` but with an extra `outFile` property in `options` and writes
the CSS and sourceMap (if requested) to the filesystem.
`options.sourceMap` can be used to specify that the source map should be saved:
- If falsy the source map will not be saved
- If `options.sourceMap === true` the source map will be saved to the
standard location of `options.file + '.map'`
- Else `options.sourceMap` specifies the path (relative to the `outFile`)
where the source map should be saved
*/
exports.renderFile = function(options) {
var newOptions = {};
for (var i in options) {
if (options.hasOwnProperty(i)) {
newOptions[i] = options[i];
}
}
if (options.sourceMap === true) {
newOptions.sourceMap = path.basename(options.outFile) + '.map';
}
newOptions.success = function(css, sourceMap) {
fs.writeFile(options.outFile, css, function(err) {
if (err) {
return error(err);
}
if (options.sourceMap) {
var dir = path.dirname(options.outFile);
var sourceMapFile = path.resolve(dir, newOptions.sourceMap);
fs.writeFile(sourceMapFile, sourceMap, function(err) {
if (err) {
return error(err);
}
success(options.outFile, sourceMapFile);
});
}
else {
success(options.outFile);
}
});
};
function error(err) {
if (options.error) {
options.error(err);
}
}
function success(css, sourceMap) {
if (options.success) {
options.success(css, sourceMap);
}
}
exports.render(newOptions);
};
exports.middleware = require('./lib/middleware'); exports.middleware = require('./lib/middleware');
/* global afterEach */
/*jshint multistr:true */ /*jshint multistr:true */
var sass = process.env.NODESASS_COVERAGE ? require('../sass-coverage') : require('../sass'); var sass = process.env.NODESASS_COVERAGE ? require('../sass-coverage') : require('../sass');
var assert = require('assert'); var assert = require('assert');
var path = require('path'); var path = require('path');
var fs = require('fs');
var badSampleFilename = 'sample.scss'; var badSampleFilename = 'sample.scss';
var sampleFilename = path.resolve(__dirname, 'sample.scss'); var sampleFilename = path.resolve(__dirname, 'sample.scss');
...@@ -187,3 +189,86 @@ describe("compile file", function() { ...@@ -187,3 +189,86 @@ describe("compile file", function() {
})); }));
}); });
}); });
describe("render to file", function() {
var outFile = path.resolve(__dirname, 'out.css'),
files = [outFile, 'out.css.map', 'foo.css.map', 'sample.css.map'];
afterEach(function() {
files.forEach(function(file) {
file = path.resolve(__dirname, file);
if (fs.existsSync(file)) {
fs.unlinkSync(file);
}
});
});
it("should compile with renderFile", function(done) {
sass.renderFile({
file: sampleFilename,
outFile: outFile,
success: function () {
var contents = fs.readFileSync(outFile);
done(assert.equal(contents, expectedRender));
},
error: function (error) {
done(error);
}
});
});
it("should raise an error for bad input", function(done) {
sass.renderFile({
file: badSampleFilename,
outFile: outFile,
success: function() {
assert(false, "success() should not be called");
done();
},
error: function() {
assert(true, "error() called");
done();
}
});
});
it("should save the sourceMap to the default file name", function(done) {
sass.renderFile({
file: sampleFilename,
outFile: outFile,
sourceMap: true,
success: function (cssFile, sourceMapFile) {
var css = fs.readFileSync(cssFile).toString();
var map = fs.readFileSync(sourceMapFile).toString();
var mapFileName = 'out.css.map';
assert.equal(path.basename(sourceMapFile), mapFileName);
assert.ok(css.indexOf('sourceMappingURL=' + mapFileName) !== -1);
assert.ok(map.indexOf('sample.scss') !== -1);
done();
},
error: function (error) {
done(error);
}
});
});
it("should save the sourceMap to a specified file name", function(done) {
var mapFileName = 'foo.css.map';
sass.renderFile({
file: sampleFilename,
outFile: outFile,
sourceMap: mapFileName,
success: function (cssFile, sourceMapFile) {
var css = fs.readFileSync(cssFile).toString();
var map = fs.readFileSync(sourceMapFile).toString();
assert.equal(path.basename(sourceMapFile), mapFileName);
assert.ok(css.indexOf('sourceMappingURL=' + mapFileName) !== -1);
assert.ok(map.indexOf('sample.scss') !== -1);
done();
},
error: function (error) {
done(error);
}
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment