mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-10-04 04:21:33 +00:00
Add hook "config" to transform configuration before generation
This commit is contained in:
+15
-2
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
};
|
||||
+15
-110
@@ -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;
|
||||
|
||||
+13
-13
@@ -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;
|
||||
|
||||
+21
-21
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user