diff options
Diffstat (limited to 'lib/generate')
-rw-r--r-- | lib/generate/config.js | 32 | ||||
-rw-r--r-- | lib/generate/ebook/index.js | 1 | ||||
-rw-r--r-- | lib/generate/fs.js | 15 | ||||
-rw-r--r-- | lib/generate/index.js | 36 | ||||
-rw-r--r-- | lib/generate/page/index.js | 10 | ||||
-rw-r--r-- | lib/generate/plugin.js | 73 |
6 files changed, 125 insertions, 42 deletions
diff --git a/lib/generate/config.js b/lib/generate/config.js index 7ec0741..fb232a6 100644 --- a/lib/generate/config.js +++ b/lib/generate/config.js @@ -1,3 +1,4 @@ +var Q = require('q'); var _ = require('lodash'); var path = require('path'); @@ -16,9 +17,10 @@ var CONFIG = { // Configuration file to use "configFile": "book", - // Book title and description (defaults are extracted from the README) + // Book metadats (somes are extracted from the README by default) "title": null, "description": null, + "isbn": null, // For ebook format, the extension to use for generation (default is detected from output extension) // "epub", "pdf", "mobi" @@ -96,10 +98,32 @@ var CONFIG = { } }; +// Return complete configuration +var defaultsConfig = function(options) { + return _.merge(options || {}, CONFIG, _.defaults); +}; + +// Read configuration from book.json +var readConfig = function(options) { + options = defaultsConfig(options); + + return Q() + .then(function() { + try { + var _config = require(path.resolve(options.input, options.configFile)); + options = _.merge(options, _.omit(_config, 'input', 'configFile', 'defaultsPlugins', 'generator')); + } + catch(err) { + // No config file: not a big deal + return Q(); + } + }) + .thenResolve(options); +}; + module.exports = { CONFIG: CONFIG, - defaults: function(options) { - return _.merge(options || {}, CONFIG, _.defaults); - } + defaults: defaultsConfig, + read: readConfig } diff --git a/lib/generate/ebook/index.js b/lib/generate/ebook/index.js index bc39e15..4ecccec 100644 --- a/lib/generate/ebook/index.js +++ b/lib/generate/ebook/index.js @@ -30,6 +30,7 @@ Generator.prototype.finish = function() { "--cover": that.options.cover, "--title": that.options.title, "--comments": that.options.description, + "--isbn": that.options.isbn, "--authors": that.options.author, "--publisher": "GitBook", "--chapter": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter ')]", diff --git a/lib/generate/fs.js b/lib/generate/fs.js index 4c232e7..50219eb 100644 --- a/lib/generate/fs.js +++ b/lib/generate/fs.js @@ -64,7 +64,20 @@ var getFiles = function(path) { module.exports = { list: getFiles, readFile: Q.denodeify(fs.readFile), - writeFile: Q.denodeify(fs.writeFile), + //writeFile: Q.denodeify(fs.writeFile), + writeFile: function(filename, data, options) { + var d = Q.defer(); + + try { + fs.writeFileSync(filename, data, options) + } catch(err) { + d.reject(err); + } + d.resolve(); + + + return d.promise; + }, mkdirp: Q.denodeify(fsExtra.mkdirp), copy: Q.denodeify(fsExtra.copy), remove: Q.denodeify(fsExtra.remove), diff --git a/lib/generate/index.js b/lib/generate/index.js index 2118c46..de1fc0e 100644 --- a/lib/generate/index.js +++ b/lib/generate/index.js @@ -48,28 +48,18 @@ var loadGenerator = function(options) { var generate = function(options) { - // Set defaults to options - options = defaultConfig.defaults(options); - - // Validate options - if (!options.input) { - return Q.reject(new Error("Need option input (book input directory)")); - } - - // Check files to get folder type (book, multilanguage book or neither) - return checkGenerator(options) - // Read config file - .then(function() { - try { - var _config = require(path.resolve(options.input, options.configFile)); + return defaultConfig.read(options) + .then(function(_options) { + options = _options; - options = _.merge(options, _.omit(_config, 'input', 'configFile', 'defaultsPlugins')); - } - catch(err) { - // No config file: not a big deal - return Q(); + // Validate options + if (!options.input) { + return Q.reject(new Error("Need option input (book input directory)")); } + + // Check files to get folder type (book, multilanguage book or neither) + return checkGenerator(options); }) // Read readme @@ -99,7 +89,9 @@ var generate = function(options) { }); }; - +/* + * Generate a multilanguage book by generating a book for each folder. + */ var generateMultiLang = function(options) { var langsSummary; options.output = options.output || path.join(options.input, "_book"); @@ -298,6 +290,9 @@ var generateBook = function(options) { // Finish generation .then(function() { + return generator.callHook("finish:before"); + }) + .then(function() { return generator.finish(); }) .then(function() { @@ -375,4 +370,5 @@ module.exports = { file: generateFile, book: generateBook, Plugin: Plugin, + config: defaultConfig }; diff --git a/lib/generate/page/index.js b/lib/generate/page/index.js index 8e44187..a926d13 100644 --- a/lib/generate/page/index.js +++ b/lib/generate/page/index.js @@ -26,6 +26,9 @@ Generator.prototype.loadTemplates = function() { this.summaryTemplate = swig.compileFile( this.plugins.template("ebook:sumary") || path.resolve(this.options.theme, 'templates/ebook/summary.html') ); + this.glossaryTemplate = swig.compileFile( + this.plugins.template("ebook:glossary") || path.resolve(this.options.theme, 'templates/ebook/glossary.html') + ); }; // Generate table of contents @@ -46,7 +49,7 @@ Generator.prototype.finish = function() { var output = path.join(this.options.output, "index.html"); var progress = parse.progress(this.options.navigation, "README.md"); - + return Q() // Write table of contents @@ -54,6 +57,11 @@ Generator.prototype.finish = function() { return that.writeToc(); }) + // Write glossary + .then(function() { + return that.writeGlossary(); + }) + // Copy cover .then(function() { return that.copyCover(); diff --git a/lib/generate/plugin.js b/lib/generate/plugin.js index 9d740a5..5ca5e92 100644 --- a/lib/generate/plugin.js +++ b/lib/generate/plugin.js @@ -4,6 +4,7 @@ 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"); @@ -152,33 +153,73 @@ Plugin.prototype.copyAssets = function(out, options) { }; -// Normalize a list of plugin name to use -Plugin.normalizeNames = function(names) { +// 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 - names = _.isString(names) ? names.split(",") : (names || []); + 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(names) - .filter(function(name) { - return name.length > 0 && name[0] == "-"; + var toremove = _.chain(plugins) + .filter(function(plugin) { + return plugin.name.length > 0 && plugin.name[0] == "-"; }) - .map(function(name) { - return name.slice(1); + .map(function(plugin) { + return plugin.name.slice(1); }) .value(); // Merge with defaults - names = _.chain(names) - .concat(Plugin.defaults) + plugins = _.chain(plugins) + .concat(_.map(Plugin.defaults, function(plugin) { + return { 'name': plugin } + })) .uniq() .value(); - // Remove plugins starting with - names = _.filter(names, function(name) { - return !_.contains(toremove, name) && !(name.length > 0 && name[0] == "-"); + // Build final list + plugins = _.filter(plugins, function(plugin) { + return !_.contains(toremove, plugin.name) && !(plugin.name.length > 0 && plugin.name[0] == "-"); }); - return names; + 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 @@ -196,7 +237,7 @@ Plugin.fromList = function(names, root, generator, options) { return plugin; }); - if (_.size(failed) > 0) return Q.reject(new Error("Error loading plugins: "+failed.join(","))); + 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; @@ -276,7 +317,7 @@ Plugin.fromList = function(names, root, generator, options) { }); }; -// Default plugins +// Default plugins added to each books Plugin.defaults = [ "mathjax" ]; |