diff options
author | Samy Pessé <samypesse@gmail.com> | 2015-01-27 15:22:42 +0100 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2015-01-27 15:22:42 +0100 |
commit | 131c19dee6db956d758ed4a63ee24dbf087a8c7f (patch) | |
tree | 9b31f135fb12a105f395f298b7468962559778df | |
parent | 870ca4da0c9fa750acba609aff8d129d5a753466 (diff) | |
download | gitbook-131c19dee6db956d758ed4a63ee24dbf087a8c7f.zip gitbook-131c19dee6db956d758ed4a63ee24dbf087a8c7f.tar.gz gitbook-131c19dee6db956d758ed4a63ee24dbf087a8c7f.tar.bz2 |
Move plugin helper methods to a specific class
-rw-r--r-- | lib/book.js | 36 | ||||
-rw-r--r-- | lib/plugin.js | 109 | ||||
-rw-r--r-- | lib/pluginslist.js | 117 | ||||
-rw-r--r-- | lib/template.js | 17 |
4 files changed, 140 insertions, 139 deletions
diff --git a/lib/book.js b/lib/book.js index 9795bc8..d1c7ece 100644 --- a/lib/book.js +++ b/lib/book.js @@ -16,10 +16,13 @@ var logger = require("./utils/logger"); var Configuration = require("./configuration"); var TemplateEngine = require("./template"); var Plugin = require("./plugin"); +var PluginsList = require("./pluginslist"); var generators = require("./generators"); var Book = function(root, context, parent) { + var that = this; + this.context = _.defaults(context || {}, { // Extend book configuration config: {}, @@ -70,7 +73,7 @@ var Book = function(root, context, parent) { this.files = []; // List of plugins - this.plugins = {}; + this.plugins = new PluginsList(this); // Structure files this.summaryFile = null; @@ -85,6 +88,9 @@ var Book = function(root, context, parent) { this.field('title', { boost: 10 }); this.field('body'); }); + + // Bind methods + _.bindAll(this); }; Book.LOG_LEVELS = { @@ -327,30 +333,12 @@ Book.prototype.parsePlugins = function() { var failed = []; // Load plugins - var pluginsList = _.map(that.options.plugins, function(plugin) { - var plugin = new Plugin(that, plugin.name); - that.log.info("load plugin", plugin.name, "...."); - - if (!plugin.isValid()) { - that.log.info.fail(); - failed.push(plugin.name); - } else { - that.log.info.ok(); - } - return plugin; - }); - - if (_.size(failed) > 0) return Q.reject(new Error("Error loading plugins: "+failed.join(",")+". Run 'gitbook install' to install plugins from NPM.")); - - that.log.info.ok(that.plugins.length+" plugins loaded"); - that.log.debug.ln("normalize plugins list"); - - return Plugin.normalize(pluginsList) - .then(function(_plugins) { - that.plugins = _plugins; + return that.plugins.load(that.options.plugins) + .then(function() { + if (_.size(that.plugins.failed) > 0) return Q.reject(new Error("Error loading plugins: "+that.plugins.failed.join(",")+". Run 'gitbook install' to install plugins from NPM.")); - // Add filters - that.template.addFilters(that.plugins.filters); + that.log.info.ok(that.plugins.length+" plugins loaded"); + that.log.debug.ln("normalize plugins list"); }); }; diff --git a/lib/plugin.js b/lib/plugin.js index ec55513..fa38e20 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -196,113 +196,4 @@ Plugin.prototype.copyAssets = function(out, options) { }, _.constant(false)); }; - -// Extract data from a list of plugin -Plugin.normalize = function(plugins, options) { - options = _.defaults(options || {}, { - assetsBase: "book" - }); - - // The raw resources extracted from each plugin - var pluginResources; - - // Map of resources - var resources = {}; - - // Map of all filters - var filters = {}; - - // Get resources of plugins - return Q.all(_.map(plugins, function(plugin) { - return plugin.getResources(options.assetsBase); - })) - - // Extract resources out - // css, js, etc ... - .then(function(_resources) { - pluginResources = _resources; - }) - .then(function() { - // Group by resource types - resources = _.chain(Plugin.RESOURCES) - .map(function(resourceType) { - // Get resources from all the plugins for this current type - return [ - // Key - resourceType, - - // Value - _.chain(pluginResources) - .pluck(resourceType) - .compact() - .flatten() - .value() - ]; - }) - .object() - .value(); - }) - - // Extract html snippets - .then(function() { - // Map of html resources by name added by each plugin - resources.html = pluginResources.reduce(function(accu, resource) { - var html = (resource && resource.html) || {}; - _.each(html, function(code, key) { - // Turn into function if not one already - if (!_.isFunction(code)) code = _.constant(code); - // Append - accu[key] = (accu[key] || []).concat([code]); - }); - - return accu; - }, {}); - }) - - // Extract filters - .then(function() { - _.each(plugins, function(plugin) { - _.each(plugin.getFilters(), function(filterFunc, filterName) { - if (filters[filterName]) { - plugin.book.log.warn.ln("Conflict in filters, '"+filterName+"' is already set"); - } else { - filters[filterName] = filterFunc; - } - }); - }); - }) - - // Return big multi-plugins object - .then(function() { - return { - 'list': plugins, - 'resources': resources, - 'filters': filters, - 'hook': function(name, data) { - return _.reduce(plugins, function(prev, plugin) { - return prev.then(function(ret) { - return plugin.callHook(name, ret); - }); - }, Q(data)); - }, - 'template': function(name) { - var withTpl = _.find(plugins, function(plugin) { - return ( - plugin.infos.templates && - plugin.infos.templates[name] - ); - }); - - if (!withTpl) return null; - return withTpl.resolveFile(withTpl.infos.templates[name]); - }, - 'html': function(tag, context, options) { - return _.map(resources.html[tag] || [], function(code) { - return code.call(context, options); - }).join("\n"); - } - }; - }); -}; - module.exports = Plugin; diff --git a/lib/pluginslist.js b/lib/pluginslist.js new file mode 100644 index 0000000..d1d276d --- /dev/null +++ b/lib/pluginslist.js @@ -0,0 +1,117 @@ +var _ = require("lodash"); +var Q = require("q"); + +var Plugin = require("./plugin"); + +var PluginsList = function(book, plugins) { + this.book = book; + this.log = this.book.log; + + // List of Plugin objects + this.plugins = []; + + // List of names of failed plugins + this.failed = []; + + // List of plugins resources + this.resources = {}; + _.each(Plugin.RESOURCES, function(resourceType) { + this.resources[resourceType] = []; + }, this); + + // Map of html snippets + this.htmlSnippets = {}; + + // Bind methods + _.bindAll(this); + + if (plugins) this.load(plugins); +}; + +// Add and load a plugin +PluginsList.prototype.load = function(plugin, options) { + var that = this; + options = _.defaults(options || {}, { + assetsBase: "book" + }); + + if (_.isArray(plugin)) { + return _.reduce(plugin, function(prev, p) { + prev.then(function() { + return that.load(p); + }); + }, Q()); + } + if (_.isString(plugin)) { + plugin = new Plugin(this.book, plugin); + } + + that.log.info("load plugin", plugin.name, "...."); + if (!plugin.isValid()) { + that.log.info.fail(); + that.failed.push(plugin.name); + return; + } else { + that.log.info.ok(); + + // Push in the list + that.plugins.push(plugin); + } + + // Extract filters + _.each(plugin.getFilters(), function(filterFunc, filterName) { + that.book.template.addFilter(filterName, filterFunc); + }); + + return Q() + .then(function() { + return plugin.getResources(options.assetsBase); + }) + + .then(function(plResources) { + // Extract js and css + _.each(Plugin.RESOURCES, function(resourceType) { + that.resources[resourceType].concat(plResources[resourceType] || []); + }); + + // Map of html resources by name added by each plugin + _.each(plResources.html || {}, function(value, tag) { + // Turn into function if not one already + if (!_.isFunction(value)) value = _.constant(value); + + that.htmlSnippets[tag] = that.htmlSnippets[tag] || []; + that.htmlSnippets[tag].push(value); + }); + }); +}; + +// Call a hook +PluginsList.prototype.hook = function(name, data) { + return _.reduce(this.plugins, function(prev, plugin) { + return prev.then(function(ret) { + return plugin.callHook(name, ret); + }); + }, Q(data)); +}; + +// Return a template from a plugin +PluginsList.prototype.template = function(name) { + var withTpl = _.find(this.plugins, function(plugin) { + return ( + plugin.infos.templates && + plugin.infos.templates[name] + ); + }); + + if (!withTpl) return null; + return withTpl.resolveFile(withTpl.infos.templates[name]); +}; + +// Return an html snippet +PluginsList.prototype.html = function(tag, context, options) { + return _.map(this.htmlSnippets[tag] || [], function(code) { + return code.call(context, options); + }).join("\n"); +}; + +module.exports = PluginsList; diff --git a/lib/template.js b/lib/template.js index 32c46de..69a1bd5 100644 --- a/lib/template.js +++ b/lib/template.js @@ -45,6 +45,7 @@ var BookLoader = nunjucks.Loader.extend({ var TemplateEngine = function(book) { this.book = book; + this.log = this.book.log; // Nunjucks env this.env = new nunjucks.Environment( @@ -66,12 +67,16 @@ var TemplateEngine = function(book) { ); }; -// Add filters -TemplateEngine.prototype.addFilters = function(filters) { - _.each(filters, function(func, key) { - this.book.log.debug.ln("add filter '"+key+"'"); - this.env.addFilter(key, func); - }, this); + +// Add filter +TemplateEngine.prototype.addFilter = function(key, filter) { + if (this.env.getFilter(filterName)) { + this.log.warn.ln("conflict in filters, '"+filterName+"' is already set"); + return false; + } + this.log.debug.ln("add filter '"+key+"'"); + this.env.addFilter(key, func, true); + return true; }; // Render a string from the book |