mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-27 04:29:05 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fb862f466f | |||
| 8d51300386 | |||
| c4b413563d | |||
| 8f852971f9 | |||
| 3c54c89464 | |||
| d07aa13822 | |||
| c218f7d0e3 | |||
| 72ad872e90 | |||
| 854f244d22 | |||
| 9acbb223db | |||
| c59fc687db | |||
| 0791b917f1 | |||
| ba182ce8e4 | |||
| 663291c515 |
@@ -19,6 +19,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Fix error in code highlighting for unknown languages
|
||||
- Accept SSH url as plugin version
|
||||
- Add templating blocks `markdown`, `asciidoc` and `markup`
|
||||
- Better search experience
|
||||
- Better default theme, more responsive and cleaner
|
||||
|
||||
## 2.6.7
|
||||
- Fix bug with filenames including spaces
|
||||
|
||||
@@ -6,11 +6,10 @@ module.exports = {
|
||||
title: 'GitBook Toolchain Documentation',
|
||||
|
||||
// Enforce use of GitBook v3
|
||||
gitbook: pkg.version,
|
||||
gitbook: '>=3.0.0-pre.0',
|
||||
|
||||
// Use the "official" theme
|
||||
plugins: ['theme-official', 'sitemap'],
|
||||
theme: 'official',
|
||||
|
||||
variables: {
|
||||
version: pkg.version
|
||||
|
||||
@@ -10,6 +10,8 @@ The following is a reference of the available data during book's parsing and the
|
||||
| `gitbook` | GitBook specific information |
|
||||
| `page` | Current page specific information |
|
||||
| `file` | File associated with the current page specific information |
|
||||
| `readme` | Information about the Readme |
|
||||
| `glossary` | Information about the Glossary |
|
||||
| `summary` | Information about the table of contents |
|
||||
| `languages` | List of languages for multi-lingual books |
|
||||
| `output` | Information about the output generator |
|
||||
@@ -71,3 +73,14 @@ Languages are defined by `{ id: 'en', title: 'English' }`.
|
||||
| `output.name` | Name of the output generator, possible values are `website`, `json`, `ebook` |
|
||||
| `output.format` | When `output.name == "ebook"`, `format` defines the ebook format that will be generated, possible values are `pdf`, `epub` or `mobi` |
|
||||
|
||||
### Readme Variables
|
||||
|
||||
| Variable | Description |
|
||||
| -------- | ----------- |
|
||||
| `readme.path` | Path to the Readme in the book |
|
||||
|
||||
### Glossary Variables
|
||||
|
||||
| Variable | Description |
|
||||
| -------- | ----------- |
|
||||
| `glossary.path` | Path to the Glossary in the book |
|
||||
|
||||
+19
-1
@@ -11,7 +11,25 @@ util.inherits(Readme, BackboneFile);
|
||||
|
||||
Readme.prototype.type = 'readme';
|
||||
|
||||
// Parse the readme content
|
||||
/*
|
||||
Return and extension of context to define the readme
|
||||
|
||||
@retrun {Object}
|
||||
*/
|
||||
Readme.prototype.getContext = function() {
|
||||
return {
|
||||
readme: {
|
||||
path: this.path
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
Parse the readme content
|
||||
|
||||
@param {String} content
|
||||
@retrun {Promise}
|
||||
*/
|
||||
Readme.prototype.parse = function(content) {
|
||||
var that = this;
|
||||
|
||||
|
||||
@@ -231,6 +231,7 @@ Summary.prototype.getContext = function() {
|
||||
|
||||
return {
|
||||
summary: {
|
||||
path: this.path,
|
||||
parts: _.map(this.parts, function(part) {
|
||||
return part.getContext(onArticle);
|
||||
})
|
||||
|
||||
+1
-10
@@ -97,16 +97,7 @@ function Book(opts) {
|
||||
Object.defineProperty(this, 'options', {
|
||||
get: function () {
|
||||
this.log.warn.ln('"options" property is deprecated, use config.get(key) instead');
|
||||
var cfg = this.config.dump();
|
||||
error.deprecateField(cfg, 'book', (this.output? this.output.name : null), '"options.generator" property is deprecated, use "output.name" instead');
|
||||
|
||||
// options.generator
|
||||
cfg.generator = this.output? this.output.name : null;
|
||||
|
||||
// options.output
|
||||
cfg.output = this.output? this.output.root() : null;
|
||||
|
||||
return cfg;
|
||||
return this.config.options;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+6
-1
@@ -3,6 +3,7 @@ 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');
|
||||
|
||||
@@ -90,6 +91,9 @@ Config.prototype.replace = function(options) {
|
||||
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
|
||||
@@ -119,7 +123,8 @@ Config.prototype.set = function(key, value) {
|
||||
|
||||
// Return a dump of the configuration
|
||||
Config.prototype.dump = function() {
|
||||
return _.cloneDeep(this.options);
|
||||
var opts = _.omit(this.options, 'generator', 'output');
|
||||
return _.cloneDeep(opts);
|
||||
};
|
||||
|
||||
// Return templating context
|
||||
|
||||
@@ -248,6 +248,7 @@ Output.prototype.getContext = function() {
|
||||
},
|
||||
this.book.getContext(),
|
||||
(this.book.isLanguageBook()? this.book.parent: this.book).langs.getContext(),
|
||||
this.book.readme.getContext(),
|
||||
this.book.summary.getContext(),
|
||||
this.book.glossary.getContext(),
|
||||
this.book.config.getContext(),
|
||||
|
||||
+2
-8
@@ -44,13 +44,7 @@ EbookOutput.prototype.finish = function() {
|
||||
|
||||
// Generate SUMMARY.html
|
||||
.then(function() {
|
||||
return that.render('summary', that.getContext())
|
||||
.then(function(html) {
|
||||
return that.writeFile(
|
||||
'SUMMARY.html',
|
||||
html
|
||||
);
|
||||
});
|
||||
return that.render('summary', 'SUMMARY.html', that.getContext());
|
||||
})
|
||||
|
||||
// Start ebook-convert
|
||||
@@ -100,7 +94,7 @@ EbookOutput.prototype.getPDFTemplate = function(tpl) {
|
||||
this.getContext()
|
||||
);
|
||||
|
||||
return this.render('pdf_'+tpl, context)
|
||||
return this.renderAsString('pdf_'+tpl, context)
|
||||
|
||||
// Inline css, include css relative to the output folder
|
||||
.then(function(output) {
|
||||
|
||||
@@ -1,22 +1,14 @@
|
||||
var _ = require('lodash');
|
||||
var path = require('path');
|
||||
var util = require('util');
|
||||
var nunjucks = require('nunjucks');
|
||||
var I18n = require('i18n-t');
|
||||
|
||||
var Promise = require('../utils/promise');
|
||||
var location = require('../utils/location');
|
||||
var fs = require('../utils/fs');
|
||||
var defaultFilters = require('../template/filters');
|
||||
var FSLoader = require('../template/fs-loader');
|
||||
var conrefsLoader = require('./conrefs');
|
||||
var Output = require('./base');
|
||||
|
||||
|
||||
// Directory for a theme with the templates
|
||||
function templatesPath(dir) {
|
||||
return path.join(dir, '_layouts');
|
||||
}
|
||||
var Promise = require('../../utils/promise');
|
||||
var location = require('../../utils/location');
|
||||
var fs = require('../../utils/fs');
|
||||
var conrefsLoader = require('../conrefs');
|
||||
var Output = require('../base');
|
||||
var setupTemplateEnv = require('./templateEnv');
|
||||
|
||||
function _WebsiteOutput() {
|
||||
Output.apply(this, arguments);
|
||||
@@ -68,58 +60,7 @@ WebsiteOutput.prototype.prepare = function() {
|
||||
that.i18n.load(i18nRoot);
|
||||
});
|
||||
|
||||
that.env = new nunjucks.Environment(new FSLoader(_.map(searchPaths, templatesPath)));
|
||||
|
||||
// Add GitBook default filters
|
||||
_.each(defaultFilters, function(fn, filter) {
|
||||
that.env.addFilter(filter, fn);
|
||||
});
|
||||
|
||||
// Translate using _i18n locales
|
||||
that.env.addFilter('t', function(s) {
|
||||
return that.i18n.t(that.book.config.get('language'), s);
|
||||
});
|
||||
|
||||
// Transform an absolute path into a relative path
|
||||
// using this.ctx.page.path
|
||||
that.env.addFilter('resolveFile', function(href) {
|
||||
return location.normalize(that.resolveForPage(this.ctx.file.path, href));
|
||||
});
|
||||
|
||||
// Test if a file exists
|
||||
that.env.addFilter('fileExists', function(href) {
|
||||
return fs.existsSync(that.resolve(href));
|
||||
});
|
||||
|
||||
// Transform a '.md' into a '.html' (README -> index)
|
||||
that.env.addFilter('contentURL', function(s) {
|
||||
return that.toURL(s);
|
||||
});
|
||||
|
||||
// Get an article using its path
|
||||
that.env.addFilter('getArticleByPath', function(s) {
|
||||
var article = that.book.summary.getArticle(s);
|
||||
if (!article) return undefined;
|
||||
|
||||
return article.getContext();
|
||||
});
|
||||
|
||||
// Relase path to an asset
|
||||
that.env.addFilter('resolveAsset', function(href) {
|
||||
href = path.join('gitbook', href);
|
||||
|
||||
// Resolve for current file
|
||||
if (this.ctx.file) {
|
||||
href = that.resolveForPage(this.ctx.file.path, '/' + href);
|
||||
}
|
||||
|
||||
// Use assets from parent
|
||||
if (that.book.isLanguageBook()) {
|
||||
href = path.join('../', href);
|
||||
}
|
||||
|
||||
return location.normalize(href);
|
||||
});
|
||||
that.searchPaths = searchPaths;
|
||||
})
|
||||
|
||||
// Copy assets from themes before copying files from book
|
||||
@@ -164,15 +105,7 @@ WebsiteOutput.prototype.onPage = function(page) {
|
||||
|
||||
// Render the page template with the same context as the json output
|
||||
.then(function() {
|
||||
return that.render('page', page.getOutputContext(that));
|
||||
})
|
||||
|
||||
// Write the HTML file
|
||||
.then(function(html) {
|
||||
return that.writeFile(
|
||||
that.outputPath(page.path),
|
||||
html
|
||||
);
|
||||
return that.render('page', that.outputPath(page.path), page.getOutputContext(that));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -204,38 +137,24 @@ WebsiteOutput.prototype.finish = function() {
|
||||
WebsiteOutput.prototype.outputMultilingualIndex = function() {
|
||||
var that = this;
|
||||
|
||||
return that.render('languages', that.getContext())
|
||||
.then(function(html) {
|
||||
return that.writeFile(
|
||||
'index.html',
|
||||
html
|
||||
);
|
||||
});
|
||||
return that.render('languages', 'index.html', that.getContext());
|
||||
};
|
||||
|
||||
// Render a template using nunjucks
|
||||
// Templates are stored in `_layouts` folders
|
||||
WebsiteOutput.prototype.render = function(tpl, context) {
|
||||
var that = this;
|
||||
/*
|
||||
Render a template as an HTML string
|
||||
Templates are stored in `_layouts` folders
|
||||
|
||||
|
||||
@param {String} tpl: template name (ex: "page")
|
||||
@param {String} outputFile: filename to write, relative to the output
|
||||
@param {Object} context: context for the page
|
||||
@return {Promise}
|
||||
*/
|
||||
WebsiteOutput.prototype.renderAsString = function(tpl, context) {
|
||||
// Calcul template name
|
||||
var filename = this.templateName(tpl);
|
||||
|
||||
context = _.extend(context, {
|
||||
template: {
|
||||
self: filename,
|
||||
getJSContext: function() {
|
||||
return {
|
||||
page: _.omit(context.page, 'content'),
|
||||
config: context.config,
|
||||
file: context.file,
|
||||
gitbook: context.gitbook,
|
||||
basePath: location.normalize(that.resolveForPage(context.file.path, './')),
|
||||
book: {
|
||||
language: context.book.language
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
plugins: {
|
||||
resources: this.resources
|
||||
},
|
||||
@@ -243,7 +162,56 @@ WebsiteOutput.prototype.render = function(tpl, context) {
|
||||
options: this.opts
|
||||
});
|
||||
|
||||
return Promise.nfcall(this.env.render.bind(this.env), filename, context);
|
||||
// Create environment
|
||||
var env = setupTemplateEnv(this, context);
|
||||
|
||||
return Promise.nfcall(env.render.bind(env), filename, context);
|
||||
};
|
||||
|
||||
/*
|
||||
Render a template using nunjucks
|
||||
Templates are stored in `_layouts` folders
|
||||
|
||||
|
||||
@param {String} tpl: template name (ex: "page")
|
||||
@param {String} outputFile: filename to write, relative to the output
|
||||
@param {Object} context: context for the page
|
||||
@return {Promise}
|
||||
*/
|
||||
WebsiteOutput.prototype.render = function(tpl, outputFile, context) {
|
||||
var that = this;
|
||||
|
||||
// Calcul relative path to the root
|
||||
var outputDirName = path.dirname(outputFile);
|
||||
var basePath = location.normalize(path.relative(outputDirName, './'));
|
||||
|
||||
// Setup complete context
|
||||
context = _.extend(context, {
|
||||
basePath: basePath,
|
||||
|
||||
template: {
|
||||
getJSContext: function() {
|
||||
return {
|
||||
page: _.omit(context.page, 'content'),
|
||||
config: context.config,
|
||||
file: context.file,
|
||||
gitbook: context.gitbook,
|
||||
basePath: basePath,
|
||||
book: {
|
||||
language: context.book.language
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return this.renderAsString(tpl, context)
|
||||
.then(function(html) {
|
||||
return that.writeFile(
|
||||
outputFile,
|
||||
html
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
// Return a complete name for a template
|
||||
@@ -252,3 +220,6 @@ WebsiteOutput.prototype.templateName = function(name) {
|
||||
};
|
||||
|
||||
module.exports = WebsiteOutput;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
var _ = require('lodash');
|
||||
var nunjucks = require('nunjucks');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var DoExtension = require('nunjucks-do')(nunjucks);
|
||||
|
||||
|
||||
var location = require('../../utils/location');
|
||||
var defaultFilters = require('../../template/filters');
|
||||
|
||||
var ThemeLoader = require('./themeLoader');
|
||||
|
||||
// Directory for a theme with the templates
|
||||
function templatesPath(dir) {
|
||||
return path.join(dir, '_layouts');
|
||||
}
|
||||
|
||||
/*
|
||||
Create and setup at Nunjucks template environment
|
||||
|
||||
@return {Nunjucks.Environment}
|
||||
*/
|
||||
function setupTemplateEnv(output, context) {
|
||||
var loader = new ThemeLoader(
|
||||
_.map(output.searchPaths, templatesPath)
|
||||
);
|
||||
var env = new nunjucks.Environment(loader);
|
||||
|
||||
env.addExtension('DoExtension', new DoExtension());
|
||||
|
||||
// Add context as global
|
||||
_.each(context, function(value, key) {
|
||||
env.addGlobal(key, value);
|
||||
});
|
||||
|
||||
// Add GitBook default filters
|
||||
_.each(defaultFilters, function(fn, filter) {
|
||||
env.addFilter(filter, fn);
|
||||
});
|
||||
|
||||
// Translate using _i18n locales
|
||||
env.addFilter('t', function t(s) {
|
||||
return output.i18n.t(output.book.config.get('language'), s);
|
||||
});
|
||||
|
||||
// Transform an absolute path into a relative path
|
||||
// using this.ctx.page.path
|
||||
env.addFilter('resolveFile', function resolveFile(href) {
|
||||
return location.normalize(output.resolveForPage(context.file.path, href));
|
||||
});
|
||||
|
||||
// Test if a file exists
|
||||
env.addFilter('fileExists', function fileExists(href) {
|
||||
return fs.existsSync(output.resolve(href));
|
||||
});
|
||||
|
||||
// Transform a '.md' into a '.html' (README -> index)
|
||||
env.addFilter('contentURL', function contentURL(s) {
|
||||
return output.toURL(s);
|
||||
});
|
||||
|
||||
// Get an article using its path
|
||||
env.addFilter('getArticleByPath', function getArticleByPath(s) {
|
||||
var article = output.book.summary.getArticle(s);
|
||||
if (!article) return undefined;
|
||||
|
||||
return article.getContext();
|
||||
});
|
||||
|
||||
// Relase path to an asset
|
||||
env.addFilter('resolveAsset', function resolveAsset(href) {
|
||||
href = path.join('gitbook', href);
|
||||
|
||||
// Resolve for current file
|
||||
if (context.file) {
|
||||
href = output.resolveForPage(context.file.path, '/' + href);
|
||||
}
|
||||
|
||||
// Use assets from parent
|
||||
if (output.book.isLanguageBook()) {
|
||||
href = path.join('../', href);
|
||||
}
|
||||
|
||||
return location.normalize(href);
|
||||
});
|
||||
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
module.exports = setupTemplateEnv;
|
||||
@@ -7,36 +7,86 @@ var nunjucks = require('nunjucks');
|
||||
Nunjucks loader similar to FileSystemLoader, but avoid infinite looping
|
||||
*/
|
||||
|
||||
/*
|
||||
Return true if a filename is relative.
|
||||
*/
|
||||
function isRelative(filename) {
|
||||
return (filename.indexOf('./') === 0 || filename.indexOf('../') === 0);
|
||||
}
|
||||
|
||||
var Loader = nunjucks.Loader.extend({
|
||||
var ThemeLoader = nunjucks.Loader.extend({
|
||||
init: function(searchPaths) {
|
||||
this.searchPaths = _.map(searchPaths, path.normalize);
|
||||
},
|
||||
|
||||
/*
|
||||
Read source of a resolved filepath
|
||||
|
||||
@param {String}
|
||||
@return {Object}
|
||||
*/
|
||||
getSource: function(fullpath) {
|
||||
if (!fullpath) return null;
|
||||
|
||||
fullpath = this.resolve(null, fullpath);
|
||||
var templateName = this.getTemplateName(fullpath);
|
||||
|
||||
if(!fullpath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
src: fs.readFileSync(fullpath, 'utf-8'),
|
||||
src: '{% do %}template = template || {}; template.stack = template.stack || []; template.stack.push(template.self); template.self = ' + JSON.stringify(templateName) + '{% enddo %}\n' +
|
||||
fs.readFileSync(fullpath, 'utf-8') +
|
||||
'\n{% do %}template.self = template.stack.pop();{% enddo %}',
|
||||
path: fullpath,
|
||||
noCache: true
|
||||
};
|
||||
},
|
||||
|
||||
// We handle absolute paths ourselves in ".resolve"
|
||||
/*
|
||||
Nunjucks calls "isRelative" to determine when to call "resolve".
|
||||
We handle absolute paths ourselves in ".resolve" so we always return true
|
||||
*/
|
||||
isRelative: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
/*
|
||||
Get original search path containing a template
|
||||
|
||||
@param {String} filepath
|
||||
@return {String} searchPath
|
||||
*/
|
||||
getSearchPath: function(filepath) {
|
||||
return _.chain(this.searchPaths)
|
||||
.sortBy(function(s) {
|
||||
return -s.length;
|
||||
})
|
||||
.find(function(basePath) {
|
||||
return (filepath && filepath.indexOf(basePath) === 0);
|
||||
})
|
||||
.value();
|
||||
},
|
||||
|
||||
/*
|
||||
Get template name from a filepath
|
||||
|
||||
@param {String} filepath
|
||||
@return {String} name
|
||||
*/
|
||||
getTemplateName: function(filepath) {
|
||||
var originalSearchPath = this.getSearchPath(filepath);
|
||||
return originalSearchPath? path.relative(originalSearchPath, filepath) : null;
|
||||
},
|
||||
|
||||
/*
|
||||
Resolve a template from a current template
|
||||
|
||||
@param {String|null} from
|
||||
@param {String} to
|
||||
@return {String|null}
|
||||
*/
|
||||
resolve: function(from, to) {
|
||||
var searchPaths = this.searchPaths;
|
||||
|
||||
@@ -46,15 +96,8 @@ var Loader = nunjucks.Loader.extend({
|
||||
}
|
||||
|
||||
// Determine in which search folder we currently are
|
||||
var originalSearchPath = _.chain(this.searchPaths)
|
||||
.sortBy(function(s) {
|
||||
return -s.length;
|
||||
})
|
||||
.find(function(basePath) {
|
||||
return (from && from.indexOf(basePath) === 0);
|
||||
})
|
||||
.value();
|
||||
var originalFilename = originalSearchPath? path.relative(originalSearchPath, from) : null;
|
||||
var originalSearchPath = this.getSearchPath(from);
|
||||
var originalFilename = this.getTemplateName(from);
|
||||
|
||||
// If we are including same file from a different search path
|
||||
// Slice the search paths to avoid including from previous ones
|
||||
@@ -77,4 +120,4 @@ var Loader = nunjucks.Loader.extend({
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Loader;
|
||||
module.exports = ThemeLoader;
|
||||
@@ -12,7 +12,12 @@ function pluginCtx(plugin) {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
// Call a function "fn" with a context of page similar to the one in GitBook v2
|
||||
/*
|
||||
Call a function "fn" with a context of page similar to the one in GitBook v2
|
||||
|
||||
@params {Page}
|
||||
@returns {String|undefined} new content of the page
|
||||
*/
|
||||
function pageHook(page, fn) {
|
||||
// Get page context
|
||||
var ctx = page.getContext().page;
|
||||
@@ -24,16 +29,26 @@ function pageHook(page, fn) {
|
||||
|
||||
// Deprecate sections
|
||||
error.deprecateField(ctx, 'sections', [
|
||||
{ content: ctx.content }
|
||||
{ content: ctx.content, type: 'normal' }
|
||||
], '"sections" property is deprecated, use page.content instead');
|
||||
|
||||
// Keep reference of original content for compatibility
|
||||
var originalContent = ctx.content;
|
||||
|
||||
return fn(ctx)
|
||||
.then(function(result) {
|
||||
// No returned value
|
||||
// Existing content will be used
|
||||
if (!result) return undefined;
|
||||
if (result.content) {
|
||||
|
||||
// GitBook 3
|
||||
// Use returned page.content if different from original content
|
||||
if (result.content != originalContent) {
|
||||
return result.content;
|
||||
}
|
||||
|
||||
// GitBook 2 compatibility
|
||||
// Finally, use page.sections
|
||||
if (result.sections) {
|
||||
return _.pluck(result.sections, 'content').join('\n');
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitbook",
|
||||
"version": "3.0.0-pre.8",
|
||||
"version": "3.0.0-pre.9",
|
||||
"homepage": "https://www.gitbook.com",
|
||||
"description": "Library and cmd utility to generate GitBooks",
|
||||
"main": "lib/index.js",
|
||||
@@ -24,9 +24,9 @@
|
||||
"gitbook-plugin-fontsettings": "1.0.3",
|
||||
"gitbook-plugin-highlight": "2.0.2",
|
||||
"gitbook-plugin-livereload": "0.0.1",
|
||||
"gitbook-plugin-search": "2.0.0",
|
||||
"gitbook-plugin-search": "2.1.0",
|
||||
"gitbook-plugin-lunr": "1.0.0",
|
||||
"gitbook-plugin-theme-default": "1.0.0-pre.7",
|
||||
"gitbook-plugin-theme-default": "1.0.0-pre.8",
|
||||
"gitbook-plugin-sharing": "1.0.2",
|
||||
"github-slugid": "1.0.1",
|
||||
"graceful-fs": "4.1.3",
|
||||
@@ -42,7 +42,7 @@
|
||||
"npm": "3.8.6",
|
||||
"npmi": "1.0.1",
|
||||
"nunjucks": "2.4.1",
|
||||
"nunjucks-autoescape": "1.0.1",
|
||||
"nunjucks-do": "1.0.0",
|
||||
"q": "1.4.1",
|
||||
"read-installed": "^4.0.3",
|
||||
"request": "2.70.0",
|
||||
|
||||
+43
-22
@@ -68,24 +68,8 @@ function setupDefaultBook(files, summary, opts) {
|
||||
}), opts);
|
||||
}
|
||||
|
||||
// Output a book with a specific generator
|
||||
function outputDefaultBook(Output, files, summary, opts) {
|
||||
return setupDefaultBook(files, summary, opts)
|
||||
.then(function(book) {
|
||||
// Parse the book
|
||||
return book.parse()
|
||||
|
||||
// Start generation
|
||||
.then(function() {
|
||||
var output = new Output(book);
|
||||
return output.generate()
|
||||
.thenResolve(output);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Output a book with a specific generator
|
||||
function outputBook(Output, files, opts) {
|
||||
// Prepare output for a book
|
||||
function setupOutput(Output, files, opts) {
|
||||
return setupBook(files, opts)
|
||||
.then(function(book) {
|
||||
// Parse the book
|
||||
@@ -93,13 +77,43 @@ function outputBook(Output, files, opts) {
|
||||
|
||||
// Start generation
|
||||
.then(function() {
|
||||
var output = new Output(book);
|
||||
return output.generate()
|
||||
.thenResolve(output);
|
||||
return new Output(book);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Prepare output for a book
|
||||
function setupDefaultOutput(Output, files, summary, opts) {
|
||||
return setupDefaultBook(files, summary, opts)
|
||||
.then(function(book) {
|
||||
// Parse the book
|
||||
return book.parse()
|
||||
|
||||
// Start generation
|
||||
.then(function() {
|
||||
return new Output(book);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Output a book with a specific generator
|
||||
function outputDefaultBook(Output, files, summary, opts) {
|
||||
return setupDefaultOutput(Output, files, summary, opts)
|
||||
.then(function(output) {
|
||||
return output.generate()
|
||||
.thenResolve(output);
|
||||
});
|
||||
}
|
||||
|
||||
// Output a book with a specific generator
|
||||
function outputBook(Output, files, opts) {
|
||||
return setupOutput(Output, files, opts)
|
||||
.then(function(output) {
|
||||
return output.generate()
|
||||
.thenResolve(output);
|
||||
});
|
||||
}
|
||||
|
||||
// Log an error
|
||||
function logError(err) {
|
||||
console.log(err.stack || err);
|
||||
@@ -107,10 +121,17 @@ function logError(err) {
|
||||
|
||||
module.exports = {
|
||||
fs: nodeFS,
|
||||
|
||||
setupFS: setupFS,
|
||||
|
||||
setupBook: setupBook,
|
||||
outputBook: outputBook,
|
||||
setupDefaultBook: setupDefaultBook,
|
||||
|
||||
setupOutput: setupOutput,
|
||||
setupDefaultOutput: setupDefaultOutput,
|
||||
|
||||
outputBook: outputBook,
|
||||
outputDefaultBook: outputDefaultBook,
|
||||
|
||||
logError: logError
|
||||
};
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "gitbook-plugin-dep1",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"gitbook": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"gitbook-plugin-dep2": "*"
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "gitbook-plugin-dep2",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"gitbook": "*"
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
hooks: {
|
||||
page: function(page) {
|
||||
page.sections[0].content = 'Hello (sections) ' + page.content;
|
||||
return page;
|
||||
}
|
||||
}
|
||||
};
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "gitbook-plugin-test-deprecated",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"gitbook": "*"
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -1,5 +1,3 @@
|
||||
var should = require('should');
|
||||
|
||||
module.exports = {
|
||||
hooks: {
|
||||
'init': function() {
|
||||
@@ -11,6 +9,10 @@ module.exports = {
|
||||
},
|
||||
'finish:before': function() {
|
||||
global._hooks.push('finish:before');
|
||||
},
|
||||
page: function(page) {
|
||||
page.content = 'Hello ' + page.content;
|
||||
return page;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -20,7 +20,8 @@ describe('Website Output', function() {
|
||||
});
|
||||
|
||||
it('should correctly copy assets', function() {
|
||||
output.should.have.file('gitbook/app.js');
|
||||
output.should.have.file('gitbook/gitbook.js');
|
||||
output.should.have.file('gitbook/theme.js');
|
||||
output.should.have.file('gitbook/images/favicon.ico');
|
||||
});
|
||||
|
||||
@@ -84,12 +85,16 @@ describe('Website Output', function() {
|
||||
});
|
||||
|
||||
it('should correctly copy assets', function() {
|
||||
output.should.have.file('gitbook/app.js');
|
||||
output.should.have.file('gitbook/gitbook.js');
|
||||
output.should.have.file('gitbook/theme.js');
|
||||
});
|
||||
|
||||
it('should not copy assets for each language', function() {
|
||||
output.should.have.not.file('en/gitbook/app.js');
|
||||
output.should.have.not.file('fr/gitbook/app.js');
|
||||
output.should.have.not.file('en/gitbook/gitbook.js');
|
||||
output.should.have.not.file('fr/gitbook/gitbook.js');
|
||||
|
||||
output.should.have.not.file('en/gitbook/theme.js');
|
||||
output.should.have.not.file('fr/gitbook/theme.js');
|
||||
});
|
||||
|
||||
it('should correctly generate an index.html', function() {
|
||||
|
||||
@@ -6,6 +6,7 @@ var registry = require('../lib/plugins/registry');
|
||||
var Output = require('../lib/output/base');
|
||||
var PluginsManager = require('../lib/plugins');
|
||||
var BookPlugin = require('../lib/plugins/plugin');
|
||||
var JSONOutput = require('../lib/output/json');
|
||||
|
||||
var PLUGINS_ROOT = path.resolve(__dirname, 'node_modules');
|
||||
|
||||
@@ -229,6 +230,42 @@ describe('Plugins', function() {
|
||||
global._hooks.should.deepEqual(['init']);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Hook "page"', function() {
|
||||
var pluginDeprecated;
|
||||
|
||||
before(function() {
|
||||
pluginDeprecated = TestPlugin(book, 'test-deprecated');
|
||||
return pluginDeprecated.load(PLUGINS_ROOT);
|
||||
});
|
||||
|
||||
it('should update content using "content" property', function() {
|
||||
return mock.setupDefaultOutput(JSONOutput)
|
||||
.then(function(output) {
|
||||
output.plugins.load(plugin);
|
||||
|
||||
return output.generate()
|
||||
.then(function() {
|
||||
var json = require(output.resolve('README.json'));
|
||||
json.page.content.should.equal('Hello <p>Hello</p>\n');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should update content using deprecated "sections" property', function() {
|
||||
return mock.setupDefaultOutput(JSONOutput)
|
||||
.then(function(output) {
|
||||
output.plugins.load(pluginDeprecated);
|
||||
|
||||
return output.generate()
|
||||
.then(function() {
|
||||
var json = require(output.resolve('README.json'));
|
||||
json.page.content.should.equal('Hello (sections) <p>Hello</p>\n');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user