wintersmith
Version:
A flexible static site generator.
152 lines (126 loc) • 4.34 kB
JavaScript
/* utils.coffee */
(function() {
var async, extend, fileExists, fileExistsSync, fs, path, pump, readJSON, readJSONSync, readdirRecursive, rfc822, stripExtension, util;
util = require('util');
fs = require('fs');
path = require('path');
async = require('async');
fileExists = fs.exists || path.exists;
fileExistsSync = fs.existsSync || path.existsSync;
extend = function(obj, mixin) {
var method, name;
for (name in mixin) {
method = mixin[name];
obj[name] = method;
}
};
stripExtension = function(filename) {
/* Remove the file-extension from *filename* */
return filename.replace(/(.+)\.[^.]+$/, '$1');
};
readJSON = function(filename, callback) {
/* Read and try to parse *filename* as JSON, *callback* with parsed object or error on fault. */
return async.waterfall([
function(callback) {
return fs.readFile(filename, callback);
}, function(buffer, callback) {
var error, rv;
try {
rv = JSON.parse(buffer.toString());
return callback(null, rv);
} catch (error1) {
error = error1;
error.filename = filename;
error.message = "parsing " + (path.basename(filename)) + ": " + error.message;
return callback(error);
}
}
], callback);
};
readJSONSync = function(filename) {
/* Synchronously read and try to parse *filename* as json. */
var buffer;
buffer = fs.readFileSync(filename);
return JSON.parse(buffer.toString());
};
readdirRecursive = function(directory, callback) {
/* Returns an array representing *directory*, including subdirectories. */
var result, walk;
result = [];
walk = function(dir, callback) {
return async.waterfall([
async.apply(fs.readdir, path.join(directory, dir)), function(filenames, callback) {
return async.forEach(filenames, function(filename, callback) {
var relname;
relname = path.join(dir, filename);
return async.waterfall([
async.apply(fs.stat, path.join(directory, relname)), function(stat, callback) {
if (stat.isDirectory()) {
return walk(relname, callback);
} else {
result.push(relname);
return callback();
}
}
], callback);
}, callback);
}
], callback);
};
return walk('', function(error) {
return callback(error, result);
});
};
pump = function(source, destination, callback) {
/* Pipe *source* stream to *destination* stream calling *callback* when done */
source.pipe(destination);
source.on('error', function(error) {
if (typeof callback === "function") {
callback(error);
}
return callback = null;
});
return destination.on('finish', function() {
if (typeof callback === "function") {
callback();
}
return callback = null;
});
};
rfc822 = function(date) {
/* return a rfc822 representation of a javascript Date object
http://www.w3.org/Protocols/rfc822/#z28
*/
var days, months, pad, time, tzoffset;
pad = function(i) {
if (i < 10) {
return '0' + i;
} else {
return i;
}
};
tzoffset = function(offset) {
var direction, hours, minutes;
hours = Math.floor(offset / 60);
minutes = Math.abs(offset % 60);
direction = hours > 0 ? '-' : '+';
return direction + pad(Math.abs(hours)) + pad(minutes);
};
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', ' Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
time = [pad(date.getHours()), pad(date.getMinutes()), pad(date.getSeconds())].join(':');
return [days[date.getDay()] + ',', pad(date.getDate()), months[date.getMonth()], date.getFullYear(), time, tzoffset(date.getTimezoneOffset())].join(' ');
};
/* Exports */
module.exports = {
fileExists: fileExists,
fileExistsSync: fileExistsSync,
extend: extend,
stripExtension: stripExtension,
readJSON: readJSON,
readJSONSync: readJSONSync,
readdirRecursive: readdirRecursive,
pump: pump,
rfc822: rfc822
};
}).call(this);