diff --git a/lib/mu.js b/lib/mu.js index 4a843ac..0c765b4 100644 --- a/lib/mu.js +++ b/lib/mu.js @@ -6,168 +6,177 @@ var util = require('util'), renderer = require('./mu/renderer'), errors = require('./mu/errors'); -var mu = module.exports = {}; +// create a mu instance for backwards compatibility +module.exports = createMu(process.cwd()); -mu.root = process.cwd(); -mu.cache = {}; +// provide a mu factory function +module.exports.createMu = createMu; -mu.fs = function (filename, callback) { - filename = filename.indexOf('/') === 0 || filename.indexOf(':\\') === 1 ? filename : path.join(mu.root, filename); - fs.readFile(filename, 'utf8', callback); -} +function createMu(root) { + var mu = {}; -/** - * Compiles a file. The result will be cached as the filename and can be - * rendered via that name. - * - * @param {String} filename The name of the file to compile. If the filename - * starts with a '/', the file is assumed to be absolute, else it is - * relative to mu.root. - * @param {Function(err, Parsed)} callback The function to call when the file has been compiled. - */ -mu.compile = function(filename, callback, unique) { - var parsed, - unique = unique || {}; - - mu.fs(filename, function (err, contents) { - if (err) { - callback(new Error('file_not_found'));//errors.fileNotFound(mu.root, filename, err))); - } - - parsed = parser.parse(contents); - mu.cache[filename] = [parsed, unique]; + mu.root = root; + mu.cache = {}; - var i = 0; - (function next(err) { - if (err) { - return callback(err); - } + mu.fs = function (filename, callback) { + filename = filename.indexOf('/') === 0 || filename.indexOf(':\\') === 1 ? filename : path.join(mu.root, filename); + fs.readFile(filename, 'utf8', callback); + } - if (i < parsed.partials.length) { - mu.compile(parsed.partials[i], next, unique); - i++; - - } else { - callback(undefined, [parsed, {}]); + /** + * Compiles a file. The result will be cached as the filename and can be + * rendered via that name. + * + * @param {String} filename The name of the file to compile. If the filename + * starts with a '/', the file is assumed to be absolute, else it is + * relative to mu.root. + * @param {Function(err, Parsed)} callback The function to call when the file has been compiled. + */ + mu.compile = function(filename, callback, unique) { + var parsed, + unique = unique || {}; + + mu.fs(filename, function (err, contents) { + if (err) { + callback(new Error('file_not_found'));//errors.fileNotFound(mu.root, filename, err))); } - }()); - }); -} - -/** - * Compiles a string into the parsed form. If `name` is provided the text - * will be cached by that name. Alternatively you can pass the return - * into mu.render. - * - * @param {String} name (Optional) The name to cache the parsed form as. - * @param {String} template The template to parse. - * @param {Function(err, Parsed)} callback (Optional) An optional callback that - * will be called when the text is parsed. This is only to unify the - * API with mu.compile. - * - * @returns {Parsed} The parsed template unless `callback` is provided. - */ -mu.compileText = function (name, template, callback) { - var parsed; - - if (typeof template === 'undefined') { - template = name; - name = undefined; + + parsed = parser.parse(contents); + mu.cache[filename] = [parsed, unique]; + + var i = 0; + (function next(err) { + if (err) { + return callback(err); + } + + if (i < parsed.partials.length) { + mu.compile(parsed.partials[i], next, unique); + i++; + + } else { + callback(undefined, [parsed, {}]); + } + }()); + }); } - - try { - parsed = parser.parse(template); + + /** + * Compiles a string into the parsed form. If `name` is provided the text + * will be cached by that name. Alternatively you can pass the return + * into mu.render. + * + * @param {String} name (Optional) The name to cache the parsed form as. + * @param {String} template The template to parse. + * @param {Function(err, Parsed)} callback (Optional) An optional callback that + * will be called when the text is parsed. This is only to unify the + * API with mu.compile. + * + * @returns {Parsed} The parsed template unless `callback` is provided. + */ + mu.compileText = function (name, template, callback) { + var parsed; - if (name) { - mu.cache[name] = [parsed, {}]; + if (typeof template === 'undefined') { + template = name; + name = undefined; } - - if (callback) callback(undefined, parsed); else return parsed; - } catch (err) { - if (callback) callback(err); else throw err; - } -} + try { + parsed = parser.parse(template); + + if (name) { + mu.cache[name] = [parsed, {}]; + } -/** - * Renders the previously parsed filename or the parsed object. - * - * @param {String|Parsed} filenameOrParsed Filename or parsed object to render. - * @param {Object} view The data to use when renderings. - * - * @returns {Stream} The render stream. - * @throws {Error(template_not_in_cache)} If filename was not found in cache. - */ -mu.render = function (filenameOrParsed, view) { - var stream, - parsed = typeof filenameOrParsed === 'object' ? - filenameOrParsed : - mu.cache[filenameOrParsed]; - - if (parsed) { - return beginRender(parsed[0].tokens, view, mu.cache); - } else { - throw new Error('template_not_in_cache'); //errors.templateNotInCache(filename))); + if (callback) callback(undefined, parsed); else return parsed; + + } catch (err) { + if (callback) callback(err); else throw err; + } } -} -mu.renderText = function (template, view, partials) { - var name, parsed, tokens, stream; - - partials = partials || {}; - partials = shallowCopy(partials); - partials.__proto__ = mu.cache; - - for (name in partials) { - if (partials.hasOwnProperty(name) && !partials[name].tokens) { - partials[name] = parser.parse(partials[name]); + /** + * Renders the previously parsed filename or the parsed object. + * + * @param {String|Parsed} filenameOrParsed Filename or parsed object to render. + * @param {Object} view The data to use when renderings. + * + * @returns {Stream} The render stream. + * @throws {Error(template_not_in_cache)} If filename was not found in cache. + */ + mu.render = function (filenameOrParsed, view) { + var stream, + parsed = typeof filenameOrParsed === 'object' ? + filenameOrParsed : + mu.cache[filenameOrParsed]; + + if (parsed) { + return beginRender(parsed[0].tokens, view, mu.cache); + } else { + throw new Error('template_not_in_cache'); //errors.templateNotInCache(filename))); } } - - parsed = parser.parse(template); - tokens = parsed.tokens; - - return beginRender(tokens, view, partials); -} -/** - * Clears all of the cache or a specific template. - * - * @param templateName String If provided only that template is removed from - * the cache, else everything is. - */ -mu.clearCache = function (templateName) { - if (templateName) { - delete mu.cache[templateName]; - } else { - mu.cache = {}; + mu.renderText = function (template, view, partials) { + var name, parsed, tokens, stream; + + partials = partials || {}; + partials = shallowCopy(partials); + partials.__proto__ = mu.cache; + + for (name in partials) { + if (partials.hasOwnProperty(name) && !partials[name].tokens) { + partials[name] = parser.parse(partials[name]); + } + } + + parsed = parser.parse(template); + tokens = parsed.tokens; + + return beginRender(tokens, view, partials); } -}; - -/** - * Compiles the template and then renders it. Uses the cache if it - * is available. - * - * @param templateName String The name of the template to render - * @param view Object The view object to inject into the template upon render - * @returns Stream THe output stream - */ -mu.compileAndRender = function (templateName, view) { - var stream = new Stream(); - var parsed = mu.cache[templateName]; - - if (parsed) { - beginRenderWithStream(parsed[0].tokens, view, mu.cache, stream); - } else { - mu.compile(templateName, function (err, parsed) { - if (err) return stream.emit('error', err); + + /** + * Clears all of the cache or a specific template. + * + * @param templateName String If provided only that template is removed from + * the cache, else everything is. + */ + mu.clearCache = function (templateName) { + if (templateName) { + delete mu.cache[templateName]; + } else { + mu.cache = {}; + } + }; + + /** + * Compiles the template and then renders it. Uses the cache if it + * is available. + * + * @param templateName String The name of the template to render + * @param view Object The view object to inject into the template upon render + * @returns Stream THe output stream + */ + mu.compileAndRender = function (templateName, view) { + var stream = new Stream(); + var parsed = mu.cache[templateName]; + + if (parsed) { beginRenderWithStream(parsed[0].tokens, view, mu.cache, stream); - }); - } - - return stream; -}; + } else { + mu.compile(templateName, function (err, parsed) { + if (err) return stream.emit('error', err); + beginRenderWithStream(parsed[0].tokens, view, mu.cache, stream); + }); + } + + return stream; + }; + return mu; +} /// Private API