diff options
author | Samy Pessé <samypesse@gmail.com> | 2016-04-22 11:00:21 +0200 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2016-04-22 11:00:21 +0200 |
commit | 4336fdb2414d460ffee68a0cc87c0cb0c85cf56e (patch) | |
tree | 279f711ab98666c892c19a7b9e4073a094f03f98 /lib/config | |
parent | 87db7cf1d412fa6fbd18e9a7e4f4755f2c0c5547 (diff) | |
download | gitbook-4336fdb2414d460ffee68a0cc87c0cb0c85cf56e.zip gitbook-4336fdb2414d460ffee68a0cc87c0cb0c85cf56e.tar.gz gitbook-4336fdb2414d460ffee68a0cc87c0cb0c85cf56e.tar.bz2 |
Base
Diffstat (limited to 'lib/config')
-rw-r--r-- | lib/config/index.js | 137 | ||||
-rw-r--r-- | lib/config/plugins.js | 67 | ||||
-rw-r--r-- | lib/config/schema.js | 188 | ||||
-rw-r--r-- | lib/config/validator.js | 28 |
4 files changed, 0 insertions, 420 deletions
diff --git a/lib/config/index.js b/lib/config/index.js deleted file mode 100644 index 6887cc2..0000000 --- a/lib/config/index.js +++ /dev/null @@ -1,137 +0,0 @@ -var _ = require('lodash'); -var semver = require('semver'); - -var gitbook = require('../gitbook'); -var Promise = require('../utils/promise'); -var error = require('../utils/error'); -var validator = require('./validator'); -var plugins = require('./plugins'); - -// Config files to tested (sorted) -var CONFIG_FILES = [ - 'book.js', - 'book.json' -]; - -/* -Config is an interface for the book's configuration stored in "book.json" (or "book.js") -*/ - -function Config(book, baseConfig) { - this.book = book; - this.fs = book.fs; - this.log = book.log; - this.path = ''; - - this.baseConfig = baseConfig || {}; - this.replace({}); -} - -// Load configuration of the book -// and verify that the configuration is satisfying -Config.prototype.load = function() { - var that = this; - var isLanguageBook = this.book.isLanguageBook(); - - // Try all potential configuration file - return Promise.some(CONFIG_FILES, function(filename) { - that.log.debug.ln('try loading configuration from', filename); - - return that.fs.loadAsObject(that.book.resolve(filename)) - .then(function(_config) { - that.log.debug.ln('configuration loaded from', filename); - - that.path = filename; - return that.replace(_config); - }) - .fail(function(err) { - if (err.code != 'MODULE_NOT_FOUND') throw(err); - else return Promise(false); - }); - }) - .then(function() { - if (!isLanguageBook) { - if (!gitbook.satisfies(that.options.gitbook)) { - throw new Error('GitBook version doesn\'t satisfy version required by the book: '+that.options.gitbook); - } - if (that.options.gitbook != '*' && !semver.satisfies(semver.inc(gitbook.version, 'patch'), that.options.gitbook)) { - that.log.warn.ln('gitbook version specified in your book.json might be too strict for future patches, \'>='+(_.first(gitbook.version.split('.'))+'.x.x')+'\' is more adequate'); - } - - that.options.plugins = plugins.toList(that.options.plugins); - } else { - // Multilingual book should inherits the plugins list from parent - that.options.plugins = that.book.parent.config.get('plugins'); - } - - that.options.gitbook = gitbook.version; - }); -}; - -// Replace the whole configuration -Config.prototype.replace = function(options) { - var that = this; - - // Extend base config - options = _.defaults(_.cloneDeep(options), this.baseConfig); - - // Validate the config - this.options = validator.validate(options); - - // options.input == book.root - Object.defineProperty(this.options, 'input', { - get: function () { - return that.book.root; - } - }); - - // options.originalInput == book.parent.root - Object.defineProperty(this.options, 'originalInput', { - get: function () { - return that.book.parent? that.book.parent.root : undefined; - } - }); - - error.deprecateField(this.options, 'generator', (this.book.output? this.book.output.name : null), '"options.generator" property is deprecated, use "output.name" instead'); - error.deprecateField(this.options, 'output', (this.book.output && this.book.output.root? this.book.output.root() : null), '"options.output" property is deprecated, use "output.root()" instead'); -}; - -// Return true if book has a configuration file -Config.prototype.exists = function() { - return Boolean(this.path); -}; - -// Return path to a structure file -// Strip the extension by default -Config.prototype.getStructure = function(name, dontStripExt) { - var filename = this.options.structure[name]; - if (dontStripExt) return filename; - - filename = filename.split('.').slice(0, -1).join('.'); - return filename; -}; - -// Return a configuration using a key and a default value -Config.prototype.get = function(key, def) { - return _.get(this.options, key, def); -}; - -// Update a configuration -Config.prototype.set = function(key, value) { - return _.set(this.options, key, value); -}; - -// Return a dump of the configuration -Config.prototype.dump = function() { - var opts = _.omit(this.options, 'generator', 'output'); - return _.cloneDeep(opts); -}; - -// Return templating context -Config.prototype.getContext = function() { - return { - config: this.book.config.dump() - }; -}; - -module.exports = Config; diff --git a/lib/config/plugins.js b/lib/config/plugins.js deleted file mode 100644 index 24f0041..0000000 --- a/lib/config/plugins.js +++ /dev/null @@ -1,67 +0,0 @@ -var _ = require('lodash'); - -// Default plugins added to each books -var DEFAULT_PLUGINS = ['highlight', 'search', 'lunr', 'sharing', 'fontsettings', 'theme-default']; - -// Return true if a plugin is a default plugin -function isDefaultPlugin(name, version) { - return _.contains(DEFAULT_PLUGINS, name); -} - -// Normalize a list of plugins to use -function normalizePluginsList(plugins) { - // Normalize list to an array - plugins = _.isString(plugins) ? plugins.split(',') : (plugins || []); - - // Remove empty parts - plugins = _.compact(plugins); - - // Divide as {name, version} to handle format like 'myplugin@1.0.0' - plugins = _.map(plugins, function(plugin) { - if (plugin.name) return plugin; - - var parts = plugin.split('@'); - var name = parts[0]; - var version = parts.slice(1).join('@'); - return { - 'name': name, - 'version': version // 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 - _.each(DEFAULT_PLUGINS, function(plugin) { - if (_.find(plugins, { name: plugin })) { - return; - } - - plugins.push({ - 'name': plugin - }); - }); - // Remove plugin that start with '-' - plugins = _.filter(plugins, function(plugin) { - return !_.contains(toremove, plugin.name) && !(plugin.name.length > 0 && plugin.name[0] == '-'); - }); - - // Remove duplicates - plugins = _.uniq(plugins, 'name'); - - return plugins; -} - -module.exports = { - isDefaultPlugin: isDefaultPlugin, - toList: normalizePluginsList -}; - diff --git a/lib/config/schema.js b/lib/config/schema.js deleted file mode 100644 index 3fb2050..0000000 --- a/lib/config/schema.js +++ /dev/null @@ -1,188 +0,0 @@ -module.exports = { - '$schema': 'http://json-schema.org/schema#', - 'id': 'https://gitbook.com/schemas/book.json', - 'title': 'GitBook Configuration', - 'type': 'object', - 'properties': { - 'root': { - 'type': 'string', - 'title': 'Path fro the root folder containing the book\'s content' - }, - 'title': { - 'type': 'string', - 'title': 'Title of the book, default is extracted from README' - }, - 'isbn': { - 'type': 'string', - 'title': 'ISBN for published book' - }, - 'author': { - 'type': 'string', - 'title': 'Name of the author' - }, - 'gitbook': { - 'type': 'string', - 'default': '*', - 'title': 'GitBook version to match' - }, - 'direction': { - 'type': 'string', - 'enum': ['ltr', 'rtl'], - 'title': 'Direction of texts, default is detected in the pages' - }, - 'theme': { - 'type': 'string', - 'default': 'default', - 'title': 'Name of the theme plugin to use' - }, - 'variables': { - 'type': 'object', - 'title': 'Templating context variables' - }, - 'plugins': { - 'oneOf': [ - { '$ref': '#/definitions/pluginsArray' }, - { '$ref': '#/definitions/pluginsString' } - ], - 'default': [] - }, - 'pluginsConfig': { - 'type': 'object', - 'title': 'Configuration for plugins' - }, - 'structure': { - 'type': 'object', - 'properties': { - 'langs': { - 'default': 'LANGS.md', - 'type': 'string', - 'title': 'File to use as languages index', - 'pattern': '^[0-9a-zA-Z ... ]+$' - }, - 'readme': { - 'default': 'README.md', - 'type': 'string', - 'title': 'File to use as preface', - 'pattern': '^[0-9a-zA-Z ... ]+$' - }, - 'glossary': { - 'default': 'GLOSSARY.md', - 'type': 'string', - 'title': 'File to use as glossary index', - 'pattern': '^[0-9a-zA-Z ... ]+$' - }, - 'summary': { - 'default': 'SUMMARY.md', - 'type': 'string', - 'title': 'File to use as table of contents', - 'pattern': '^[0-9a-zA-Z ... ]+$' - } - }, - 'additionalProperties': false - }, - 'pdf': { - 'type': 'object', - 'title': 'PDF specific configurations', - 'properties': { - 'pageNumbers': { - 'type': 'boolean', - 'default': true, - 'title': 'Add page numbers to the bottom of every page' - }, - 'fontSize': { - 'type': 'integer', - 'minimum': 8, - 'maximum': 30, - 'default': 12, - 'title': 'Font size for the PDF output' - }, - 'fontFamily': { - 'type': 'string', - 'default': 'Arial', - 'title': 'Font family for the PDF output' - }, - 'paperSize': { - 'type': 'string', - 'enum': ['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'legal', 'letter'], - 'default': 'a4', - 'title': 'Paper size for the PDF' - }, - 'chapterMark': { - 'type': 'string', - 'enum': ['pagebreak', 'rule', 'both', 'none'], - 'default': 'pagebreak', - 'title': 'How to mark detected chapters' - }, - 'pageBreaksBefore': { - 'type': 'string', - 'default': '/', - 'title': 'An XPath expression. Page breaks are inserted before the specified elements. To disable use the expression: "/"' - }, - 'margin': { - 'type': 'object', - 'properties': { - 'right': { - 'type': 'integer', - 'title': 'Right Margin', - 'minimum': 0, - 'maximum': 100, - 'default': 62 - }, - 'left': { - 'type': 'integer', - 'title': 'Left Margin', - 'minimum': 0, - 'maximum': 100, - 'default': 62 - }, - 'top': { - 'type': 'integer', - 'title': 'Top Margin', - 'minimum': 0, - 'maximum': 100, - 'default': 56 - }, - 'bottom': { - 'type': 'integer', - 'title': 'Bottom Margin', - 'minimum': 0, - 'maximum': 100, - 'default': 56 - } - } - } - } - } - }, - 'required': [], - 'definitions': { - 'pluginsArray': { - 'type': 'array', - 'items': { - 'oneOf': [ - { '$ref': '#/definitions/pluginObject' }, - { '$ref': '#/definitions/pluginString' } - ] - } - }, - 'pluginsString': { - 'type': 'string' - }, - 'pluginString': { - 'type': 'string' - }, - 'pluginObject': { - 'type': 'object', - 'properties': { - 'name': { - 'type': 'string' - }, - 'version': { - 'type': 'string' - } - }, - 'additionalProperties': false, - 'required': ['name'] - } - } -}; diff --git a/lib/config/validator.js b/lib/config/validator.js deleted file mode 100644 index 764b19a..0000000 --- a/lib/config/validator.js +++ /dev/null @@ -1,28 +0,0 @@ -var jsonschema = require('jsonschema'); -var jsonSchemaDefaults = require('json-schema-defaults'); -var mergeDefaults = require('merge-defaults'); - -var schema = require('./schema'); -var error = require('../utils/error'); - -// Validate a book.json content -// And return a mix with the default value -function validate(bookJson) { - var v = new jsonschema.Validator(); - var result = v.validate(bookJson, schema, { - propertyName: 'config' - }); - - // Throw error - if (result.errors.length > 0) { - throw new error.ConfigurationError(new Error(result.errors[0].stack)); - } - - // Insert default values - var defaults = jsonSchemaDefaults(schema); - return mergeDefaults(bookJson, defaults); -} - -module.exports = { - validate: validate -}; |