diff options
-rw-r--r-- | README.md | 35 | ||||
-rw-r--r-- | bin/build.js | 45 | ||||
-rw-r--r-- | bin/utils.js | 54 | ||||
-rw-r--r-- | lib/generate/generator.js | 4 | ||||
-rw-r--r-- | lib/generate/index.js | 32 | ||||
-rw-r--r-- | lib/generate/plugin.js | 16 | ||||
-rw-r--r-- | lib/generate/site/index.js | 33 | ||||
-rw-r--r-- | lib/parse/git.js | 56 | ||||
-rw-r--r-- | lib/parse/index.js | 3 | ||||
-rw-r--r-- | package.json | 2 |
10 files changed, 168 insertions, 112 deletions
@@ -30,14 +30,37 @@ $ gitbook build ./repository --output=./outputFolder Options for commands `build` and `serve` are: ``` --t, --title <name> Name of the book to generate, defaults to repo name --i, --intro <intro> Description of the book to generate --g, --github <repo_path> ID of github repo like : username/repo -o, --output <directory> Path to output directory, defaults to ./_book -f, --format <name> Change generation format, defaults to site, availables are: site, page, pdf, json ---githubHost <url> The url of the github host (defaults to https://github.com/) ---plugins <plugins> List of plugins to use separated by "," ---pluginsConfig <json file> JSON File containing plugins configuration +--config <config file> Configuration file to use, defualt to book.json +``` + +GitBook load the default configuration from a `book.json` file in the repository if it exists. + +Here are the options that can be stored in this file: + +``` +{ + // Folders to use for output (caution: it override the value from the command line) + output: null, + + // Generator to use for building (caution: it override the value from the command line) + generator: "site", + + // Book title and description (defaults are extracted from the README) + title: null, + description: null, + + // GitHub informations (defaults are extracted using git) + github: null, + githubHost: 'https://github.com/', + + // Plugins list, can contain "-name" for removing default plugins + plugins: [], + + // Global configuration for plugins + pluginsConfig: {} +} ``` You can publish your books to our index by visiting [GitBook.io](http://www.gitbook.io) diff --git a/bin/build.js b/bin/build.js index 37415bd..257715d 100644 --- a/bin/build.js +++ b/bin/build.js @@ -12,12 +12,7 @@ var buildCommand = function(command) { return command .option('-o, --output <directory>', 'Path to output directory, defaults to ./_book') .option('-f, --format <name>', 'Change generation format, defaults to site, availables are: '+_.keys(generators).join(", ")) - .option('-t, --title <name>', 'Name of the book to generate, default is extracted from readme') - .option('-i, --intro <intro>', 'Description of the book to generate, default is extracted from readme') - .option('--plugins <plugins>', 'List of plugins to use separated by ","') - .option('--pluginsConfig <json file>', 'JSON File containing plugins configuration') - .option('-g, --github <repo_path>', 'ID of github repo like : username/repo') - .option('--githubHost <url>', 'The url of the github host (defaults to https://github.com/'); + .option('--config <config file>', 'Configuration file to use, defualt to book.json') }; @@ -26,37 +21,15 @@ var makeBuildFunc = function(converter) { dir = dir || process.cwd(); outputDir = options.output; - // Read plugins config - var pluginsConfig = {}; - if (options.pluginsConfig) { - pluginsConfig = JSON.parse(fs.readFileSync(options.pluginsConfig)) - } - - console.log('Starting build ...'); - // Get repo's URL - return utils.gitURL(dir) - .then(function(url) { - // Get ID of repo - return utils.githubID(url); - }, function(err) { - return null; - }) - .then(function(repoID) { - return converter( - _.extend({}, options || {}, { - input: dir, - output: outputDir, - title: options.title, - description: options.intro, - github: options.github || repoID, - githubHost: options.githubHost, - generator: options.format, - plugins: options.plugins, - pluginsConfig: pluginsConfig - }) - ); - }) + return converter( + _.extend({}, options || {}, { + input: dir, + output: outputDir, + generator: options.format, + configFile: options.config + }) + ) .then(function(output) { console.log("Successfuly built !"); return output; diff --git a/bin/utils.js b/bin/utils.js index 45bc7d5..b43936f 100644 --- a/bin/utils.js +++ b/bin/utils.js @@ -4,60 +4,9 @@ var _ = require('lodash'); var http = require('http'); var send = require('send'); -var cp = require('child_process'); var path = require('path'); -var url = require('url'); - var Gaze = require('gaze').Gaze; - -// Get the remote of a given repo -function gitURL(path) { - var d = Q.defer(); - - cp.exec("git config --get remote.origin.url", { - cwd: path, - env: process.env, - }, function(err, stdout, stderr) { - if(err) { - return d.reject(err); - } - - return d.resolve(stdout); - }); - - return d.promise - .then(function(output) { - return output.replace(/(\r\n|\n|\r)/gm, ""); - }); -} - -// Poorman's parsing -// Parse a git URL to a github ID : username/reponame -function githubID(_url) { - // Remove .git if it's in _url - var sliceEnd = _url.slice(-4) === '.git' ? -4 : _url.length; - - // Detect HTTPS repos - var parsed = url.parse(_url); - if(parsed.protocol === 'https:' && parsed.host === 'github.com') { - return parsed.path.slice(1, sliceEnd); - } - - // Detect SSH repos - if(_url.indexOf('git@') === 0) { - return _url.split(':', 2)[1].slice(0, sliceEnd); - } - - // None found - return null; -} - -function titleCase(str) -{ - return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}); -} - function watch(dir) { var d = Q.defer(); dir = path.resolve(dir); @@ -88,9 +37,6 @@ function logError(err) { // Exports module.exports = { - gitURL: gitURL, - githubID: githubID, - titleCase: titleCase, watch: watch, logError: logError }; diff --git a/lib/generate/generator.js b/lib/generate/generator.js index 144af23..ecd646c 100644 --- a/lib/generate/generator.js +++ b/lib/generate/generator.js @@ -12,8 +12,8 @@ var BaseGenerator = function(options) { this.plugins = []; }; -BaseGenerator.prototype.callHook = function(name) { - return this.plugins.hook(name, this); +BaseGenerator.prototype.callHook = function(name, data) { + return this.plugins.hook(name, this, data); }; BaseGenerator.prototype.loadPlugins = function() { diff --git a/lib/generate/index.js b/lib/generate/index.js index 0c3e693..898e71f 100644 --- a/lib/generate/index.js +++ b/lib/generate/index.js @@ -31,6 +31,9 @@ var generate = function(options) { input: null, output: null, + // Config file (relative to input) + configFile: "book.json", + // Output generator generator: "site", @@ -63,6 +66,35 @@ var generate = function(options) { // Clean output folder return fs.remove(options.output) + // Read config file + .then(function() { + return fs.readFile(path.resolve(options.input, options.configFile)) + .then(function(_config) { + // Extend current config + _config = JSON.parse(_config); + _config = _.omit(_config, 'input', 'configFile'); + + _.extend(options, _config); + }, function() { + // No config file: not a big deal + return Q(); + }) + }) + + // Get repo's URL + .then(function() { + return parse.git.url(options.input) + .then(function(_url) { + // Get ID of repo + return parse.git.githubID(_url); + }, function(err) { + return null; + }) + .then(function(repoId) { + options.github = options.github || repoId; + }); + }) + .then(function() { return fs.mkdirp(options.output); }) diff --git a/lib/generate/plugin.js b/lib/generate/plugin.js index d92b918..6b30073 100644 --- a/lib/generate/plugin.js +++ b/lib/generate/plugin.js @@ -74,15 +74,15 @@ Plugin.prototype.resolveFile = function(filename) { }; // Resolve file path -Plugin.prototype.callHook = function(name, args) { +Plugin.prototype.callHook = function(name, context, data) { var hookFunc = this.infos.hooks? this.infos.hooks[name] : null; - args = _.isArray(args) ? args : [args]; + data = data || {}; - if (!hookFunc) return Q(); + if (!hookFunc) return Q(data); return Q() .then(function() { - return hookFunc.apply(null, args); + return hookFunc.apply(context, [data]); }); }; @@ -159,12 +159,12 @@ Plugin.fromList = function(names, root) { return Q({ 'list': plugins, 'resources': resources, - 'hook': function(name, args) { + 'hook': function(name, context, data) { return _.reduce(plugins, function(prev, plugin) { - return prev.then(function() { - return plugin.callHook(name, args); + return prev.then(function(ret) { + return plugin.callHook(name, context, ret); }) - }, Q()); + }, Q(data)); }, 'template': function(name) { var withTpl = _.find(plugins, function(plugin) { diff --git a/lib/generate/site/index.js b/lib/generate/site/index.js index f8986df..87be7b4 100644 --- a/lib/generate/site/index.js +++ b/lib/generate/site/index.js @@ -59,8 +59,11 @@ Generator.prototype.loadPlugins = function() { }; // Generate a template -Generator.prototype._writeTemplate = function(tpl, options, output) { +Generator.prototype._writeTemplate = function(tpl, options, output, interpolate) { var that = this; + + interpolate = interpolate || _.identity; + return Q() .then(function(sections) { return tpl(_.extend({ @@ -80,6 +83,7 @@ Generator.prototype._writeTemplate = function(tpl, options, output) { pluginsConfig: JSON.stringify(that.options.pluginsConfig) }, options)); }) + .then(interpolate) .then(function(html) { return fs.writeFile( output, @@ -107,6 +111,15 @@ Generator.prototype.convertFile = function(content, _input) { return Q() .then(function() { + // Send content to plugins + return that.callHook("page:before", { + path: _input, + content: content + }); + }) + .then(function(_content) { + content = _content.content; + // Lex page return parse.lex(content); }) @@ -124,17 +137,29 @@ Generator.prototype.convertFile = function(content, _input) { }); }) .then(function(sections) { + // Use plugin hook + return that.callHook("page", { + path: _input, + sections: sections + }) + }) + .then(function(_page) { that.manifest.add("CACHE", _output); return that._writeTemplate(that.template, { - progress: progress, + progress: _page.progress, _input: _input, - content: sections, + content: _page.sections, basePath: basePath, staticBase: path.join(basePath, "gitbook"), - }, output); + }, output, function(html) { + return that.callHook("page:after", { + path: _input, + content: html + }).get("content") + }); }); }; diff --git a/lib/parse/git.js b/lib/parse/git.js new file mode 100644 index 0000000..4478f20 --- /dev/null +++ b/lib/parse/git.js @@ -0,0 +1,56 @@ +var Q = require('q'); +var _ = require('lodash'); +var cp = require('child_process'); +var url = require('url'); + +// Get the remote of a given repo +function gitURL(path) { + var d = Q.defer(); + + cp.exec("git config --get remote.origin.url", { + cwd: path, + env: process.env, + }, function(err, stdout, stderr) { + if(err) { + return d.reject(err); + } + + return d.resolve(stdout); + }); + + return d.promise + .then(function(output) { + return output.replace(/(\r\n|\n|\r)/gm, ""); + }); +} + +// Poorman's parsing +// Parse a git URL to a github ID : username/reponame +function githubID(_url) { + // Remove .git if it's in _url + var sliceEnd = _url.slice(-4) === '.git' ? -4 : _url.length; + + // Detect HTTPS repos + var parsed = url.parse(_url); + if(parsed.protocol === 'https:' && parsed.host === 'github.com') { + return parsed.path.slice(1, sliceEnd); + } + + // Detect SSH repos + if(_url.indexOf('git@') === 0) { + return _url.split(':', 2)[1].slice(0, sliceEnd); + } + + // None found + return null; +} + +function titleCase(str) { + return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}); +} + +module.exports = { + url: gitURL, + githubID: githubID, + titleCase: titleCase +}; diff --git a/lib/parse/index.js b/lib/parse/index.js index 0ebb03a..bb7779f 100644 --- a/lib/parse/index.js +++ b/lib/parse/index.js @@ -5,5 +5,6 @@ module.exports = { lex: require('./lex'), progress: require('./progress'), navigation: require('./navigation'), - readme: require('./readme') + readme: require('./readme'), + git: require('./git') }; diff --git a/package.json b/package.json index 778b5b2..ad4b13b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gitbook", - "version": "0.3.1", + "version": "0.4.0", "homepage": "http://www.gitbook.io/", "description": "Library and cmd utility to generate GitBooks", "main": "lib/index.js", |