summaryrefslogtreecommitdiffstats
path: root/lib/generate/plugin.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/generate/plugin.js')
-rw-r--r--lib/generate/plugin.js325
1 files changed, 0 insertions, 325 deletions
diff --git a/lib/generate/plugin.js b/lib/generate/plugin.js
deleted file mode 100644
index 5ca5e92..0000000
--- a/lib/generate/plugin.js
+++ /dev/null
@@ -1,325 +0,0 @@
-var _ = require("lodash");
-var Q = require("q");
-var semver = require("semver");
-var path = require("path");
-var url = require("url");
-var fs = require("./fs");
-var npmi = require('npmi');
-var resolve = require('resolve');
-
-var pkg = require("../../package.json");
-
-var RESOURCES = ["js", "css"];
-
-var Plugin = function(name, root, generator) {
- this.name = name;
- this.root = root;
- this.packageInfos = {};
- this.infos = {};
- this.generator = generator;
-
- // Bind methods
- _.bindAll(this);
-
- _.each([
- "gitbook-plugin-"+name,
- "gitbook-theme-"+name,
- "gitbook-"+name,
- name,
- ], function(_name) {
- if (this.load(_name, __dirname)) return false;
- if (this.load(_name, path.resolve(root))) return false;
- }, this);
-};
-
-// Load from a name
-Plugin.prototype.load = function(name, baseDir) {
- try {
- var res = resolve.sync(name+"/package.json", { basedir: baseDir });
-
- this.baseDir = path.dirname(res);
- this.packageInfos = require(res);
- this.infos = require(resolve.sync(name, { basedir: baseDir }));
- this.name = name;
-
- return true;
- } catch (e) {
- return false;
- }
-};
-
-Plugin.prototype.normalizeResource = function(resource) {
- // Parse the resource path
- var parsed = url.parse(resource);
-
- // This is a remote resource
- // so we will simply link to using it's URL
- if (parsed.protocol) {
- return {
- "url": resource
- };
- }
-
- // This will be copied over from disk
- // and shipped with the book's build
- return { "path": this.name+"/"+resource };
-};
-
-// Return resources
-Plugin.prototype._getResources = function(base) {
- base = base || "book";
- var book = this.infos[base];
-
- // Nothing specified, fallback to default
- if (!book) {
- return Q({});
- }
-
- // Dynamic function
- if(typeof book === "function") {
- // Call giving it the context of our generator
- return Q().then(book.bind(this.generator));
- }
-
- // Plain data object
- return Q(_.cloneDeep(book));
-};
-
-// Normalize resources and return them
-Plugin.prototype.getResources = function(base) {
- var that = this;
-
- return this._getResources(base)
- .then(function(resources) {
-
- _.each(RESOURCES, function(resourceType) {
- resources[resourceType] = (resources[resourceType] || []).map(that.normalizeResource);
- });
-
- return resources;
- });
-};
-
-// Test if it's a valid plugin
-Plugin.prototype.isValid = function() {
- return (
- this.packageInfos &&
- this.packageInfos.name &&
- this.packageInfos.engines &&
- this.packageInfos.engines.gitbook &&
- semver.satisfies(pkg.version, this.packageInfos.engines.gitbook)
- );
-};
-
-// Resolve file path
-Plugin.prototype.resolveFile = function(filename) {
- return path.resolve(this.baseDir, filename);
-};
-
-// Resolve file path
-Plugin.prototype.callHook = function(name, data) {
- // Our generator will be the context to apply
- var context = this.generator;
-
- var hookFunc = this.infos.hooks? this.infos.hooks[name] : null;
- data = data || {};
-
- if (!hookFunc) return Q(data);
-
- return Q()
- .then(function() {
- return hookFunc.apply(context, [data]);
- });
-};
-
-// Copy plugin assets fodler
-Plugin.prototype.copyAssets = function(out, options) {
- var that = this;
- options = _.defaults(options || {}, {
- base: "book"
- });
-
- return this.getResources(options.base)
- .get('assets')
- .then(function(assets) {
- // Assets are undefined
- if(!assets) return false;
-
- return fs.copy(
- that.resolveFile(assets),
- out
- ).then(_.constant(true));
- }, _.constant(false));
-};
-
-
-// Install a list of plugin
-Plugin.install = function(options) {
- // Normalize list of plugins
- var plugins = Plugin.normalizeList(options.plugins);
-
- // Install plugins one by one
- return _.reduce(plugins, function(prev, plugin) {
- return prev.then(function() {
- var fullname = "gitbook-plugin-"+plugin.name;
- console.log("Install plugin", plugin.name, "from npm ("+fullname+") with version", (plugin.version || "*"));
- return Q.nfcall(npmi, {
- 'name': fullname,
- 'version': plugin.version,
- 'path': options.input,
- 'npmLoad': {
- 'loglevel': 'silent',
- 'loaded': false,
- 'prefix': options.input
- }
- });
- });
- }, Q());
-};
-
-// Normalize a list of plugins to use
-Plugin.normalizeList = function(plugins) {
- // Normalize list to an array
- plugins = _.isString(plugins) ? plugins.split(",") : (plugins || []);
-
- // Divide as {name, version} to handle format like "myplugin@1.0.0"
- plugins = _.map(plugins, function(plugin) {
- var parts = plugin.split("@");
- return {
- 'name': parts[0],
- 'version': parts[1] // optional
- }
- });
-
- // List plugins to remove
- var toremove = _.chain(plugins)
- .filter(function(plugin) {
- return plugin.name.length > 0 && plugin.name[0] == "-";
- })
- .map(function(plugin) {
- return plugin.name.slice(1);
- })
- .value();
-
- // Merge with defaults
- plugins = _.chain(plugins)
- .concat(_.map(Plugin.defaults, function(plugin) {
- return { 'name': plugin }
- }))
- .uniq()
- .value();
-
- // Build final list
- plugins = _.filter(plugins, function(plugin) {
- return !_.contains(toremove, plugin.name) && !(plugin.name.length > 0 && plugin.name[0] == "-");
- });
-
- return plugins;
-};
-
-// Normalize a list of plugin name to use
-Plugin.normalizeNames = function(plugins) {
- return _.pluck(Plugin.normalizeList(plugins), "name");
-};
-
-// Extract data from a list of plugin
-Plugin.fromList = function(names, root, generator, options) {
- options = _.defaults(options || {}, {
- assetsBase: "book"
- });
-
- var failed = [];
-
- // Load plugins
- var plugins = _.map(names, function(name) {
- var plugin = new Plugin(name, root, generator);
- if (!plugin.isValid()) failed.push(name);
- return plugin;
- });
-
- if (_.size(failed) > 0) return Q.reject(new Error("Error loading plugins: "+failed.join(",")+". Run 'gitbook install' to install plugins from NPM."));
-
- // The raw resources extracted from each plugin
- var pluginResources;
-
- // 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;
- // Group by resource types
- return _.chain(RESOURCES)
- .map(function(resourceType) {
- // Get resources from all the plugins for this current type
- return [
- // Key
- resourceType,
- // Value
- _.chain(resources)
- .pluck(resourceType)
- .compact()
- .flatten()
- .value()
- ];
- })
- .object()
- .value();
- })
- // Extract html snippets
- .then(function(resources) {
- // 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;
- }, {});
-
- return resources;
- })
- // Return big multi-plugin object
- .then(function(resources) {
- return {
- 'list': plugins,
- 'resources': resources,
- '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");
- }
- };
- });
-};
-
-// Default plugins added to each books
-Plugin.defaults = [
- "mathjax"
-];
-
-module.exports = Plugin;