Skip to content

Commit

Permalink
Refactoring modular precompilers.
Browse files Browse the repository at this point in the history
* Reintroduce the option for multiple compiled stylesheets.
* Allow for multiple extensions with --style option.
* Simplify precompiler scripts.
  • Loading branch information
hughsk committed Nov 26, 2012
1 parent 4acbbd9 commit 8d80a8d
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 140 deletions.
86 changes: 62 additions & 24 deletions bin/kss-node
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ var kss = require(__dirname + '/../lib/kss.js'),
optimist = require('optimist'),
marked = require('marked'),
wrench = require('wrench'),
stylus =require('stylus'),
stylus = require('stylus'),
async = require('async'),
util = require('util'),
less = require('less'),
path = require('path'),
Expand All @@ -27,9 +28,8 @@ var kss = require(__dirname + '/../lib/kss.js'),
* CLI argument parsing, thanks to Substack's optimist.
* @type {Object}
*/
var preCompSwitches = '--css [file] ';
argv = require('optimist')
.usage('Usage:\n $0 sourcedir [destdir] --init [directory] --style [file]')
.usage('Usage:\n $0 sourcedir [destdir] --init [directory] --{style,less,sass,stylus} [file]')
.check(function(args) {
if (args._.length < 1 && !args.init) {
throw new Error('Please provide a source directory');
Expand All @@ -42,7 +42,23 @@ argv = require('optimist')

.string('s')
.alias('s', 'style')
.describe('s', 'Compile and include a stylesheet')
.describe('s', 'Compile and include a stylesheet - the precompiler is chosen based on file extension')

.string('l')
.alias('l', 'less')
.describe('l', 'Compile and include a LESS stylesheet')

.string('y')
.alias('y', 'stylus')
.describe('y', 'Compile and include a Stylus stylesheet')

.string('S')
.alias('S', 'sass')
.describe('S', 'Compile and include a SASS stylesheet')

.string('c')
.alias('c', 'css')
.describe('c', 'Compile and include a CSS stylesheet')

.alias('i', 'init')
.describe('i', 'Create a new styleguide template to work from')
Expand Down Expand Up @@ -100,6 +116,7 @@ wrench.copyDirSyncRecursive(
// Generate the static HTML pages in the next tick, i.e. after the other functions have
// been defined and handlebars helpers set up.
process.nextTick(function() {
console.log('...compiling LESS');
less.render('@import "' + path.relative(process.cwd(), options.destinationDirectory) + '/public/kss.less";', function(err, css) {
if (err) {
console.error(err);
Expand All @@ -108,11 +125,11 @@ process.nextTick(function() {

css = cleanCss.process(css);

console.log('...compiling LESS');
// Write the compiled LESS styles from the template.
fs.writeFileSync(options.destinationDirectory + '/public/kss.css', css, 'utf8');

console.log('...parsing your styleguide');

kss.traverse(options.sourceDirectory, {
multiline : true,
markdown : true,
Expand Down Expand Up @@ -163,33 +180,54 @@ process.nextTick(function() {

// Compile LESS/Stylus/CSS files into a single "style.css" if required
generateStylesheet = function(argv) {
var projectStyle = argv.style,
stylebuffer = '',
compilers = preCompiler.compilers,
count = 1,
type,
fext = projectStyle.match(/(?:\.([^.]+))?$/)[1];
var compilers = preCompiler.compilers,
files

console.log('...compiling additional stylesheets');

// Vanilla CSS
if (fext === 'css') {
saveStylesheet(fs.readFileSync(projectStyle));
files = [ false, 'less', 'stylus', 'sass', 'css' ].map(function (type) {
var key = type || 'style';

// Or some pre-compile stuff
} else {
if (!argv[key]) return;

return {
files: Array.isArray(argv[key]) ? argv[key] : [argv[key]]
, type: type
};
});

async.reduce(files, [], function (combined, group, next) {
if (!group) return next(null, combined)

for (type in compilers) if (compilers.hasOwnProperty(type)) {

if (compilers[type].ext === fext) {
async.map(group.files, function (filename, next) {
var type = group.type
, extension

console.log('...' + compilers[type].name);
compilers[type].render(path.relative(process.cwd(), projectStyle), function (css) {
saveStylesheet(css);
});
// Type-guessing for --style option
if (!type) {
extension = path.extname(filename).slice(1)
Object.keys(compilers).forEach(function(name) {
if (compilers[name].extensions.indexOf(extension) !== -1) type = name
})
type = type || 'CSS'
}
}
}

console.log(' - ' + filename + ' (' + type + ')')

if (type === 'CSS') return next(null, fs.readFileSync(filename, 'utf8'))
compilers[type].render(filename, next)

}, function(err, output) {
if (err) return next(err)
combined += '\n'
combined += output.join('\n')
return next(null, combined)
});
}, function (err, combined) {
if (err) throw err
saveStylesheet(combined)
});
};

// Used by generateStylesheet to minify and then
Expand Down
62 changes: 27 additions & 35 deletions lib/precompiler.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,30 @@
var fs = require('fs'),
compilerPath = __dirname + '/precompilers/',

init = function (compilerPath) {
var precomp = {
mask: '',
count: '',
compilers: {}
};

// Read all files from compilerPath
// fs.readdir(compilerPath, function (err, files) {
var files = fs.readdirSync(compilerPath);

for(var i in files) if (files.hasOwnProperty(i)) {

var filePath = compilerPath + files[i],
module = require(filePath);

// If the file is a valid compiler include it
if (module.name && module.ext && module.render) {

precomp.compilers[module.ext] = module;
precomp.mask += '|\\.' + module.ext;
precomp.count++;

// Otherwise throw an error
} else {
throw new Error('Invalid precompiler: ' + filePath);
}
}

precomp.mask = new RegExp(precomp.mask.substring(1) + '|\\.css');

return precomp;
path = require('path'),
compilerPath = __dirname + '/precompilers/';

var precomp = {
mask: '',
count: 0,
compilers: {}
};

// Read all files from compilerPath
var files = fs.readdirSync(compilerPath);

files.forEach(function(filename) {
var filePath = path.resolve(compilerPath, filename),
module = require(filePath);

if (module.name && module.extensions && module.render) {
precomp.compilers[module.name] = module;
precomp.mask += '|\\.'
precomp.mask += module.extensions.join('|\\.');
precomp.count += 1;
} else {
throw new Error('Invalid precompiler: ' + filePath);
}
})

precomp.mask = new RegExp(precomp.mask.substring(1) + '|\\.css');

module.exports = init(compilerPath)
module.exports = precomp;
42 changes: 15 additions & 27 deletions lib/precompilers/less.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
var fs = require('fs'),
less = require('less'),
lessCompile = module.exports = {};

lessCompile = {
// Name of the stylesheet language
lessCompile.name = 'LESS';

// Name of the stylesheet language
name: 'LESS',
// File extension for that language
lessCompile.extensions = ['less'];

// File extension for that language
ext: 'less',

// CLI parameter
param: 'l',

/**
* Compiles the passed file to css and passes
* the resulting css to the given callback
*
* @param {String} file The file to compile
* @param {Function} cb callback(css)
*/
render: function (file, cb) {
less.render("@import '" + file + "';", function (err, css) {
if (err) {
throw err;
}
cb(css);
});
}
};

module.exports = lessCompile;
/**
* Compiles the passed file to css and passes
* the resulting css to the given callback
*
* @param {String} file The file to compile
* @param {Function} callback (err, css)
*/
lessCompile.render = function (file, callback) {
less.render("@import '" + file + "';", callback);
};
45 changes: 19 additions & 26 deletions lib/precompilers/sass.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
var fs = require('fs'),
sass = require('sass'),
sassCompile = module.exports = {};

sassCompile = {
// Name of the stylesheet language
sassCompile.name = 'SASS';

// Name of the stylesheet language
name: 'SASS',
// File extension for that language
sassCompile.extensions = ['sass'];

// File extension for that language
ext: 'sass',

/**
* Compiles the passed file to css and passes
* the resulting css to the given callback
*
* @param {String} file The file to compile
* @param {Function} cb callback(css)
*/
render: function (file, cb) {
// sass.render("@import '" + file + "';", function (err, css) {
// if (err) {
// throw new Error(err);
// }
// cb(css);
// });
var css = sass.render("@import '" + file + "';");
cb(css);
}
};

module.exports = sassCompile;
/**
* Compiles the passed file to css and passes
* the resulting css to the given callback
*
* @param {String} file The file to compile
* @param {Function} callback (err, css)
*/
sassCompile.render = function (file, callback) {
try {
callback(null, sass.render("@import '" + file + "';"));
} catch(e) {
return callback(e)
}
};
42 changes: 15 additions & 27 deletions lib/precompilers/stylus.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
var fs = require('fs'),
stylus = require('stylus'),
stylusCompile = module.exports = {};

stylusCompile = {
// Name of the stylesheet language
stylusCompile.name = 'Stylus';

// Name of the stylesheet language
name: 'Stylus',
// File extension for that language
stylusCompile.extensions = ['styl', 'stylus'];

// File extension for that language
ext: 'styl',

// CLI parameter
param: 's',

/**
* Compiles the passed file to css and passes
* the resulting css to the given callback
*
* @param {String} file The file to compile
* @param {Function} cb callback(css)
*/
render: function (file, cb) {
stylus.render("@import '" + file + "';", function (err, css) {
if (err) {
throw err;
}
cb(css);
});
}
};

module.exports = stylusCompile;
/**
* Compiles the passed file to css and passes
* the resulting css to the given callback
*
* @param {String} file The file to compile
* @param {Function} callback (err, css)
*/
stylusCompile.render = function (file, callback) {
stylus.render("@import '" + file + "';", callback);
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"stylus": "0.30.x",
"sass": "0.5.x",
"optimist": "0.3.x",
"clean-css": "0.3.x"
"clean-css": "0.3.x",
"async": "0.1.x"
},
"devDependencies": {
"mocha": "0.14.x"
Expand Down

0 comments on commit 8d80a8d

Please sign in to comment.