diff options
author | Samy Pessé <samypesse@gmail.com> | 2015-10-12 10:43:14 +0200 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2015-10-12 10:43:14 +0200 |
commit | 9ba1075f4866131f790388ebabc1b8636926dd7f (patch) | |
tree | 38ba7f7bb414fc8c8589901c90d4863b800614c6 | |
parent | 4ae5b2e05001df9bdf8c5b64f8a82725e14d6414 (diff) | |
download | gitbook-9ba1075f4866131f790388ebabc1b8636926dd7f.zip gitbook-9ba1075f4866131f790388ebabc1b8636926dd7f.tar.gz gitbook-9ba1075f4866131f790388ebabc1b8636926dd7f.tar.bz2 |
Add hook "config" to transform configuration before generation
-rw-r--r-- | lib/book.js | 17 | ||||
-rw-r--r-- | lib/config_default.js | 108 | ||||
-rw-r--r-- | lib/configuration.js | 125 | ||||
-rw-r--r-- | lib/generator.js | 26 | ||||
-rw-r--r-- | lib/plugin.js | 42 |
5 files changed, 172 insertions, 146 deletions
diff --git a/lib/book.js b/lib/book.js index 72f0ec2..39d4719 100644 --- a/lib/book.js +++ b/lib/book.js @@ -178,6 +178,14 @@ Book.prototype.generate = function(generator) { return generator.prepare(); }) + // Transform configuration + .then(function() { + return that.callHook('config', that.config.dump()) + .then(function(newConfig) { + that.config.replace(newConfig); + }); + }) + // Generate content .then(function() { if (that.isMultilingual()) { @@ -238,13 +246,13 @@ Book.prototype.generate = function(generator) { // Finish generation .then(function() { - return generator.callHook('finish:before'); + return that.callHook('finish:before'); }) .then(function() { return generator.finish(); }) .then(function() { - return generator.callHook('finish'); + return that.callHook('finish'); }) .then(function() { that.log.info.ln('generation is finished'); @@ -793,4 +801,9 @@ Book.prototype.normError = function(err, opts, defs) { return err; }; +// Call a hook in plugins +Book.prototype.callHook = function(name, data) { + return this.plugins.hook(name, data); +}; + module.exports= Book; diff --git a/lib/config_default.js b/lib/config_default.js new file mode 100644 index 0000000..328531c --- /dev/null +++ b/lib/config_default.js @@ -0,0 +1,108 @@ +var path = require('path'); + +module.exports = { + // Options that can't be extend + 'configFile': 'book', + 'generator': 'website', + 'extension': null, + + // Book metadats (somes are extracted from the README by default) + 'title': null, + 'description': null, + 'isbn': null, + 'language': 'en', + 'direction': null, + 'author': null, + + // version of gitbook to use + 'gitbook': '*', + + // Structure + 'structure': { + 'langs': 'LANGS.md', + 'readme': 'README.md', + 'glossary': 'GLOSSARY.md', + 'summary': 'SUMMARY.md' + }, + + // CSS Styles + 'styles': { + 'website': 'styles/website.css', + 'print': 'styles/print.css', + 'ebook': 'styles/ebook.css', + 'pdf': 'styles/pdf.css', + 'mobi': 'styles/mobi.css', + 'epub': 'styles/epub.css' + }, + + // Plugins list, can contain '-name' for removing default plugins + 'plugins': [], + + // Global configuration for plugins + 'pluginsConfig': {}, + + // Variables for templating + 'variables': {}, + + // Set another theme with your own layout + // It's recommended to use plugins or add more options for default theme, though + // See https://github.com/GitbookIO/gitbook/issues/209 + 'theme': path.resolve(__dirname, '../theme'), + + // Links in template (null: default, false: remove, string: new value) + 'links': { + // Custom links at top of sidebar + 'sidebar': { + // 'Custom link name': 'https://customlink.com' + }, + + // Sharing links + 'sharing': { + 'google': null, + 'facebook': null, + 'twitter': null, + 'weibo': null, + 'all': null + } + }, + + + // Options for PDF generation + 'pdf': { + // Add toc at the end of the file + 'toc': true, + + // Add page numbers to the bottom of every page + 'pageNumbers': false, + + // Font size for the file content + 'fontSize': 12, + + // Paper size for the pdf + // Choices are [u’a0’, u’a1’, u’a2’, u’a3’, u’a4’, u’a5’, u’a6’, u’b0’, u’b1’, u’b2’, u’b3’, u’b4’, u’b5’, u’b6’, u’legal’, u’letter’] + 'paperSize': 'a4', + + // How to mark detected chapters. + // Choices are “pagebreak”, “rule”, 'both' or “none”. + 'chapterMark' : 'pagebreak', + + // An XPath expression. Page breaks are inserted before the specified elements. + // To disable use the expression: '/' + 'pageBreaksBefore': '/', + + // Margin (in pts) + // Note: 72 pts equals 1 inch + 'margin': { + 'right': 62, + 'left': 62, + 'top': 56, + 'bottom': 56 + }, + + // Header HTML template. Available variables: _PAGENUM_, _TITLE_, _AUTHOR_ and _SECTION_. + 'headerTemplate': null, + + // Footer HTML template. Available variables: _PAGENUM_, _TITLE_, _AUTHOR_ and _SECTION_. + 'footerTemplate': null + } +}; diff --git a/lib/configuration.js b/lib/configuration.js index 7488fae..24d435b 100644 --- a/lib/configuration.js +++ b/lib/configuration.js @@ -1,12 +1,13 @@ var _ = require('lodash'); var Q = require('q'); -var fs = require('fs'); var path = require('path'); var semver = require('semver'); var pkg = require('../package.json'); var i18n = require('./utils/i18n'); +var DEFAULT_CONFIG = require('./config_default'); + // Default plugins added to each books var DEFAULT_PLUGINS = ['highlight', 'search', 'sharing', 'fontsettings']; @@ -85,9 +86,7 @@ var Configuration = function(book, options) { var that = this; this.book = book; - - this.options = _.cloneDeep(Configuration.DEFAULT); - this.options = _.merge(this.options, options || {}); + this.replace(options); // options.input == book.root Object.defineProperty(this.options, 'input', { @@ -169,6 +168,17 @@ Configuration.prototype.extend = function(options) { _.extend(this.options, options); }; +// Replace the configuration +Configuration.prototype.replace = function(options) { + this.options = _.cloneDeep(DEFAULT_CONFIG); + this.options = _.merge(this.options, options || {}); +}; + +// Dump configuration as json object +Configuration.prototype.dump = function() { + return _.cloneDeep(this.options); +}; + // Get structure file Configuration.prototype.getStructure = function(name) { return this.options.structure[name].split('.').slice(0, -1).join('.'); @@ -185,111 +195,6 @@ Configuration.prototype.get = function(key, def) { }; // Default configuration -Configuration.DEFAULT = { - // Options that can't be extend - 'configFile': 'book', - 'generator': 'website', - 'extension': null, - - // Book metadats (somes are extracted from the README by default) - 'title': null, - 'description': null, - 'isbn': null, - 'language': 'en', - 'direction': null, - 'author': null, - - // version of gitbook to use - 'gitbook': '*', - - // Structure - 'structure': { - 'langs': 'LANGS.md', - 'readme': 'README.md', - 'glossary': 'GLOSSARY.md', - 'summary': 'SUMMARY.md' - }, - - // CSS Styles - 'styles': { - 'website': 'styles/website.css', - 'print': 'styles/print.css', - 'ebook': 'styles/ebook.css', - 'pdf': 'styles/pdf.css', - 'mobi': 'styles/mobi.css', - 'epub': 'styles/epub.css' - }, - - // Plugins list, can contain '-name' for removing default plugins - 'plugins': [], - - // Global configuration for plugins - 'pluginsConfig': {}, - - // Variables for templating - 'variables': {}, - - // Set another theme with your own layout - // It's recommended to use plugins or add more options for default theme, though - // See https://github.com/GitbookIO/gitbook/issues/209 - 'theme': path.resolve(__dirname, '../theme'), - - // Links in template (null: default, false: remove, string: new value) - 'links': { - // Custom links at top of sidebar - 'sidebar': { - // 'Custom link name': 'https://customlink.com' - }, - - // Sharing links - 'sharing': { - 'google': null, - 'facebook': null, - 'twitter': null, - 'weibo': null, - 'all': null - } - }, - - - // Options for PDF generation - 'pdf': { - // Add toc at the end of the file - 'toc': true, - - // Add page numbers to the bottom of every page - 'pageNumbers': false, - - // Font size for the file content - 'fontSize': 12, - - // Paper size for the pdf - // Choices are [u’a0’, u’a1’, u’a2’, u’a3’, u’a4’, u’a5’, u’a6’, u’b0’, u’b1’, u’b2’, u’b3’, u’b4’, u’b5’, u’b6’, u’legal’, u’letter’] - 'paperSize': 'a4', - - // How to mark detected chapters. - // Choices are “pagebreak”, “rule”, 'both' or “none”. - 'chapterMark' : 'pagebreak', - - // An XPath expression. Page breaks are inserted before the specified elements. - // To disable use the expression: '/' - 'pageBreaksBefore': '/', - - // Margin (in pts) - // Note: 72 pts equals 1 inch - 'margin': { - 'right': 62, - 'left': 62, - 'top': 56, - 'bottom': 56 - }, - - // Header HTML template. Available variables: _PAGENUM_, _TITLE_, _AUTHOR_ and _SECTION_. - 'headerTemplate': null, - - // Footer HTML template. Available variables: _PAGENUM_, _TITLE_, _AUTHOR_ and _SECTION_. - 'footerTemplate': null - } -}; +Configuration.DEFAULT = DEFAULT_CONFIG; module.exports= Configuration; diff --git a/lib/generator.js b/lib/generator.js index fca5b3c..4e280d8 100644 --- a/lib/generator.js +++ b/lib/generator.js @@ -1,12 +1,12 @@ -var _ = require("lodash"); -var path = require("path"); -var Q = require("q"); -var fs = require("./utils/fs"); +var _ = require('lodash'); +var path = require('path'); +var Q = require('q'); +var fs = require('./utils/fs'); var BaseGenerator = function(book) { this.book = book; - Object.defineProperty(this, "options", { + Object.defineProperty(this, 'options', { get: function () { return this.book.options; } @@ -16,19 +16,19 @@ var BaseGenerator = function(book) { }; BaseGenerator.prototype.callHook = function(name, data) { - return this.book.plugins.hook(name, data); + return this.book.callHook(name, data); }; // Prepare the genertor BaseGenerator.prototype.prepare = function() { var that = this; - return that.callHook("init"); + return that.callHook('init'); }; // Write a parsed file to the output BaseGenerator.prototype.convertFile = function(input) { - return Q.reject(new Error("Could not convert "+input)); + return Q.reject(new Error('Could not convert '+input)); }; // Copy file to the output (non parsable) @@ -51,16 +51,16 @@ BaseGenerator.prototype.copyCover = function() { var that = this; return Q.all([ - fs.copy(that.book.resolve("cover.jpg"), path.join(that.options.output, "cover.jpg")), - fs.copy(that.book.resolve("cover_small.jpg"), path.join(that.options.output, "cover_small.jpg")) + fs.copy(that.book.resolve('cover.jpg'), path.join(that.options.output, 'cover.jpg')), + fs.copy(that.book.resolve('cover_small.jpg'), path.join(that.options.output, 'cover_small.jpg')) ]) .fail(function() { // If orignaly from multi-lang, try copy from parent if (!that.book.isSubBook()) return; return Q.all([ - fs.copy(path.join(that.book.parentRoot(), "cover.jpg"), path.join(that.options.output, "cover.jpg")), - fs.copy(path.join(that.book.parentRoot(), "cover_small.jpg"), path.join(that.options.output, "cover_small.jpg")) + fs.copy(path.join(that.book.parentRoot(), 'cover.jpg'), path.join(that.options.output, 'cover.jpg')), + fs.copy(path.join(that.book.parentRoot(), 'cover_small.jpg'), path.join(that.options.output, 'cover_small.jpg')) ]); }) .fail(function() { @@ -70,7 +70,7 @@ BaseGenerator.prototype.copyCover = function() { // At teh end of the generation BaseGenerator.prototype.finish = function() { - return Q.reject(new Error("Could not finish generation")); + return Q.reject(new Error('Could not finish generation')); }; module.exports = BaseGenerator; diff --git a/lib/plugin.js b/lib/plugin.js index 5e1c427..e3ac7bc 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -1,12 +1,12 @@ -var _ = require("lodash"); -var Q = require("q"); -var semver = require("semver"); -var path = require("path"); -var url = require("url"); -var fs = require("./utils/fs"); -var resolve = require("resolve"); +var _ = require('lodash'); +var Q = require('q'); +var semver = require('semver'); +var path = require('path'); +var url = require('url'); +var fs = require('./utils/fs'); +var resolve = require('resolve'); -var pkg = require("../package.json"); +var pkg = require('../package.json'); var Plugin = function(book, name) { this.book = book; @@ -18,8 +18,8 @@ var Plugin = function(book, name) { _.bindAll(this); _.each([ - "gitbook-plugin-"+name, - "gitbook-"+name, + 'gitbook-plugin-'+name, + 'gitbook-'+name, name, ], function(_name) { // Load from the book @@ -31,15 +31,15 @@ var Plugin = function(book, name) { }; // Type of plugins resources -Plugin.RESOURCES = ["js", "css"]; +Plugin.RESOURCES = ['js', 'css']; Plugin.HOOKS = [ - "init", "finish", "finish:before", "page", "page:before" + 'init', 'finish', 'finish:before', 'config', 'page', 'page:before' ]; // Load from a name Plugin.prototype.load = function(name, baseDir) { try { - var res = resolve.sync(name+"/package.json", { basedir: baseDir }); + var res = resolve.sync(name+'/package.json', { basedir: baseDir }); this.baseDir = path.dirname(res); this.packageInfos = require(res); @@ -62,13 +62,13 @@ Plugin.prototype.normalizeResource = function(resource) { // so we will simply link to using it's URL if (parsed.protocol) { return { - "url": resource + 'url': resource }; } // This will be copied over from disk // and shipped with the book's build - return { "path": this.name+"/"+resource }; + return { 'path': this.name+'/'+resource }; }; // Return resources @@ -77,7 +77,7 @@ Plugin.prototype._getResources = function(base) { var book = this.infos[base]; // Compatibility with version 1.x.x - if (base == "website") book = book || this.infos.book; + if (base == 'website') book = book || this.infos.book; // Nothing specified, fallback to default if (!book) { @@ -85,7 +85,7 @@ Plugin.prototype._getResources = function(base) { } // Dynamic function - if(typeof book === "function") { + if(typeof book === 'function') { // Call giving it the context of our book return Q().then(book.bind(this.book)); } @@ -133,7 +133,7 @@ Plugin.prototype.isValid = function() { // Valid hooks _.each(this.infos.hooks, function(hook, hookName) { if (_.contains(Plugin.HOOKS, hookName)) return; - that.book.log.warn.ln("Hook '"+hookName+" 'used by plugin '"+that.packageInfos.name+"' has been removed or is deprecated"); + that.book.log.warn.ln('Hook ''+hookName+' 'used by plugin ''+that.packageInfos.name+'' has been removed or is deprecated'); }); return isValid; @@ -154,8 +154,8 @@ Plugin.prototype.callHook = function(name, data) { if (!hookFunc) return Q(data); - this.book.log.debug.ln("call hook", name); - if (!_.contains(Plugin.HOOKS, name)) this.book.log.warn.ln("hook '"+name+"' used by plugin '"+this.name+"' is deprecated, and will be removed in the coming versions"); + this.book.log.debug.ln('call hook', name); + if (!_.contains(Plugin.HOOKS, name)) this.book.log.warn.ln('hook ''+name+'' used by plugin ''+this.name+'' is deprecated, and will be removed in the coming versions'); return Q() .then(function() { @@ -168,7 +168,7 @@ Plugin.prototype.copyAssets = function(out, base) { var that = this; return this.getResources(base) - .get("assets") + .get('assets') .then(function(assets) { // Assets are undefined if(!assets) return false; |