Server side processor support. Fixes #227. Not supporting Traceur.

This commit is contained in:
Remy Sharp 2012-07-21 15:54:27 +01:00
parent 16f73b4b8d
commit 2a89dbbc7c
3 changed files with 97 additions and 6 deletions

View File

@ -6,6 +6,7 @@ var async = require('asyncjs'),
custom = require('../custom'),
blacklist = require('../blacklist'),
scripts = require('../../scripts.json'),
processors = require('../processors'),
Observable = utils.Observable;
module.exports = Observable.extend({
@ -74,6 +75,7 @@ module.exports = Observable.extend({
}
});
},
// TODO decide whether this is used anymore
getBinSource: function (req, res) {
res.contentType('json');
var output = JSON.stringify(this.templateFromBin(req.bin));
@ -84,13 +86,40 @@ module.exports = Observable.extend({
res.send(output);
},
getBinSourceFile: function (req, res) {
var format = req.params.format;
var format = req.params.format,
settings = req.bin.settings || {},
reverseProcessorLookup = {};
if (format === 'js' || format === 'json') {
format = 'javascript';
}
if (format === 'md') {
format = 'markdown';
}
if (settings.processors) {
// first shuffle the bin around so they can request .less and get the .css panel...yeah, funky
// { html: 'markdown' }
for (var key in settings.processors) {
reverseProcessorLookup[settings.processors[key]] = key;
}
// if we want the raw preprocessed content, just map
if (reverseProcessorLookup[format]) {
req.bin[format] = req.bin[reverseProcessorLookup[format]];
} else if (settings.processors[format]) {
// else we need to convert and process the source
if (processors[settings.processors[format]] !== undefined) {
req.bin[format] = processors[settings.processors[format]](req.bin[format]);
// this delete ensures it doesn't happen again (in case we're looking at .html)
delete req.bin.settings.processors[format];
}
}
}
res.contentType(format);
if (format !== 'html') {
if (format === 'js' || format === 'json') {
format = 'javascript';
}
res.send(req.bin[format]);
} else {
this.getBinPreview(req, res);
@ -314,6 +343,7 @@ module.exports = Observable.extend({
if (!result) {
return next(new errors.NotFound('Could not find bin: ' + req.params.bin));
} else {
result.settings = JSON.parse(result.settings || '{}');
req.bin = result;
// manually add the full url to the bin to allow templates access
req.bin.permalink = helpers.urlForBin(req.bin, true);
@ -461,7 +491,7 @@ module.exports = Observable.extend({
stream: false,
code: bin.url || null,
revision: bin.url ? (bin.revision || 1) : null,
processors: JSON.parse(bin.settings || '{ "processors": {} }').processors
processors: bin.settings.processors || {}
},
settings: options.settings || {panels: []}
};
@ -492,6 +522,15 @@ module.exports = Observable.extend({
});
},
formatPreview: function (bin, options, fn) {
if (bin.settings && bin.settings.processors) {
for (var panel in bin.settings.processors) {
if (processors[bin.settings.processors[panel]] !== undefined) {
bin['original_' + panel] = bin[panel];
bin[panel] = processors[bin.settings.processors[panel]](bin[panel]);
}
}
}
var formatted = bin.html || '',
helpers = this.helpers,
insert = [],

52
lib/processors/index.js Normal file
View File

@ -0,0 +1,52 @@
// 1. preload all the available preprocessors
var path = require('path'),
root = path.resolve(path.join(__dirname, '../../')),
jade = require(root + '/public/js/vendor/jade'),
coffee = require(root + '/public/js/vendor/coffee-script'),
markdown = require(root + '/public/js/vendor/markdown'),
less = require('less'),
stylus = require(root + '/public/js/vendor/stylus');
module.exports = {
coffee: function (source) {
var renderedCode = '';
try {
renderedCode = coffee.compile(source, {
bare: true
});
} catch (e) {
console && console.error(e.message);
}
return renderedCode;
},
jade: function (source) {
return jade.compile(source, { pretty: true })();
},
markdown: function (source) {
return markdown.toHTML(source);
},
less: function (source) {
var css = '';
less.Parser().parse(source, function (err, result) {
if (err) {
console && console.error(err);
return source;
}
css = result.toCSS().trim();
});
return css;
},
stylus: function (source) {
var css = '';
stylus(source).render(function (err, result) {
if (err) {
console && console.error(err);
return;
}
css = result.trim();
});
return css;
}
};

View File

@ -76,7 +76,7 @@ module.exports = function (app) {
// Source
app.get('/:bin/:rev?/source', binHandler.getBinSource);
app.get('/:bin/:rev?.:format(js|json|css|html)', binHandler.getBinSourceFile);
app.get('/:bin/:rev?.:format(js|json|css|html|md|markdown|stylus|less|coffee|jade)', binHandler.getBinSourceFile);
app.get('/:bin/:rev?/:format(js)', function (req, res) {
// Redirect legacy /js suffix to the new .js extension.
res.redirect(301, req.path.replace(/\/js$/, '.js'));