mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-26 20:27:00 +00:00
Compare commits
22 Commits
3.2.0-pre.1
...
3.2.2
| Author | SHA1 | Date | |
|---|---|---|---|
| ad425b9772 | |||
| 5238fa352c | |||
| 32183b6650 | |||
| cb3d6a7f01 | |||
| c978f0ab21 | |||
| 33ff60cee7 | |||
| 33d7e022e6 | |||
| 09782b964b | |||
| 7938ee8ec6 | |||
| 2e8e4f63d7 | |||
| b9fa6c3051 | |||
| 9c071dade5 | |||
| 56e44651fa | |||
| 42fac98992 | |||
| 4f5513add0 | |||
| 90cbfc0596 | |||
| 38ab9fa05a | |||
| 12e20c5fcc | |||
| 6b103f4532 | |||
| d4fa5c18a8 | |||
| 2a116dfdb0 | |||
| 0349f54f3c |
@@ -0,0 +1,19 @@
|
||||
Thank you for giving us your feedback! We listed some guidelines to help you:
|
||||
|
||||
If possible, open separate issues for each bug report. Avoid grouping bugs that are unrelated.
|
||||
|
||||
### What is the current behavior?
|
||||
|
||||
If the current behavior is a bug, please provide the steps to reproduce. if possible, provide the GitBook version being used (`gitbook -V`) and the system infromations (OS and version).
|
||||
|
||||
### What is the expected behavior?
|
||||
|
||||
How do you think, or how would you like it should behave.
|
||||
|
||||
#### For GitBook.com
|
||||
|
||||
Provide, if possible, your username and the URL of the concerned book.
|
||||
|
||||
----
|
||||
|
||||
The GitBook Team
|
||||
@@ -1,5 +1,8 @@
|
||||
sudo: false
|
||||
language: node_js
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
node_js:
|
||||
- "stable"
|
||||
- "4.1"
|
||||
|
||||
+11
-1
@@ -2,10 +2,20 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## 3.2.0 (pre)
|
||||
## 3.2.2
|
||||
- Fix catching parsing errors leading to possible missing pages in generated book
|
||||
- Rollback markdown parser to `kramed` until `markup-it` is stable enough
|
||||
|
||||
## 3.2.1
|
||||
- Fix bug on Firefox when navigating to an url containing an hash
|
||||
- Update nunjucks to fix JS error when page contains a lot of templating blocks
|
||||
|
||||
## 3.2.0
|
||||
- Switch markdown parser from `kramed` to `markup-it`
|
||||
- Fix support of `|` in tables
|
||||
- Fix access to `output.name` in templating
|
||||
- Fix i18n for website and PDF
|
||||
- Fix minor scrolling issues on website
|
||||
- Improve options of default search indexer (keywords, disabling per pages)
|
||||
- Improve pertinence of search results
|
||||
|
||||
|
||||
@@ -23,5 +23,7 @@ More than 50,000 books have been published on [GitBook.com](https://www.gitbook.
|
||||
### Documentation
|
||||
|
||||
- [DuckDuckHack Documentation](http://docs.duckduckhack.com) by [DuckDuckGo](https://duckduckgo.com/about)
|
||||
- [Loomio Handbook](http://loomio.coop/) by [Loomio](https://www.loomio.org/)
|
||||
- [Enspiral Handbook](http://handbook.enspiral.com/) by [Enspiral](http://enspiral.com/)
|
||||
- This documentation
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### Testing your plugin locally
|
||||
|
||||
Testing your plugin on your book before plushing it is possible using [npm link](https://docs.npmjs.com/cli/link).
|
||||
Testing your plugin on your book before publishing it is possible using [npm link](https://docs.npmjs.com/cli/link).
|
||||
|
||||
In the plugin's folder, run:
|
||||
|
||||
@@ -10,7 +10,7 @@ In the plugin's folder, run:
|
||||
$ npm link
|
||||
```
|
||||
|
||||
The nin your book's folder:
|
||||
Then in your book's folder:
|
||||
|
||||
```
|
||||
$ npm link gitbook-plugin-<plugin's name>
|
||||
|
||||
@@ -6,6 +6,7 @@ module.exports = {
|
||||
// Models
|
||||
Book: require('./models/book'),
|
||||
FS: require('./models/fs'),
|
||||
File: require('./models/file'),
|
||||
Summary: require('./models/summary'),
|
||||
Glossary: require('./models/glossary'),
|
||||
Config: require('./models/config'),
|
||||
|
||||
@@ -18,6 +18,10 @@ module.exports = {
|
||||
'type': 'string',
|
||||
'title': 'ISBN for published book'
|
||||
},
|
||||
'language': {
|
||||
'type': 'string',
|
||||
'title': 'Language of the book'
|
||||
},
|
||||
'author': {
|
||||
'type': 'string',
|
||||
'title': 'Name of the author'
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @return {Config}
|
||||
*/
|
||||
function editPlugin(config, pluginName, pluginConfig) {
|
||||
return config.set('pluginsConfig.'+pluginName, pluginConfig);
|
||||
return config.setValue('pluginsConfig.'+pluginName, pluginConfig);
|
||||
}
|
||||
|
||||
module.exports = editPlugin;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Return the configuration for a plugin
|
||||
* @param {Config} config
|
||||
* @param {String} pluginName
|
||||
* @return {Object}
|
||||
*/
|
||||
function getPluginConfig(config, pluginName) {
|
||||
var pluginsConfig = config.getValues().get('pluginsConfig');
|
||||
if (pluginsConfig === undefined) {
|
||||
return {};
|
||||
}
|
||||
var pluginConf = pluginsConfig.get(pluginName);
|
||||
if (pluginConf === undefined) {
|
||||
return {};
|
||||
} else {
|
||||
return pluginConf.toJS();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = getPluginConfig;
|
||||
@@ -5,5 +5,6 @@ module.exports = {
|
||||
togglePlugin: require('./togglePlugin'),
|
||||
editPlugin: require('./editPlugin'),
|
||||
hasPlugin: require('./hasPlugin'),
|
||||
getPluginConfig: require('./getPluginConfig'),
|
||||
isDefaultPlugin: require('./isDefaultPlugin')
|
||||
};
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
var Immutable = require('immutable');
|
||||
|
||||
var Output = require('../../models/output');
|
||||
var Book = require('../../models/book');
|
||||
var parseBook = require('../../parse/parseBook');
|
||||
var createMockFS = require('../../fs/mock');
|
||||
var preparePlugins = require('../preparePlugins');
|
||||
|
||||
/**
|
||||
* Create an output using a generator
|
||||
*
|
||||
* FOR TESTING PURPOSE ONLY
|
||||
*
|
||||
* @param {Generator} generator
|
||||
* @param {Map<String:String|Map>} files
|
||||
* @return {Promise<Output>}
|
||||
*/
|
||||
function createMockOutput(generator, files, options) {
|
||||
var fs = createMockFS(files);
|
||||
var book = Book.createForFS(fs);
|
||||
var state = generator.State? generator.State({}) : Immutable.Map();
|
||||
|
||||
book = book.setLogLevel('disabled');
|
||||
options = generator.Options(options);
|
||||
|
||||
return parseBook(book)
|
||||
.then(function(resultBook) {
|
||||
return new Output({
|
||||
book: resultBook,
|
||||
options: options,
|
||||
state: state,
|
||||
generator: generator.name
|
||||
});
|
||||
})
|
||||
.then(preparePlugins);
|
||||
}
|
||||
|
||||
module.exports = createMockOutput;
|
||||
@@ -1,4 +1,4 @@
|
||||
var generateMock = require('../generateMock');
|
||||
var generateMock = require('./generateMock');
|
||||
var EbookGenerator = require('../ebook');
|
||||
|
||||
describe('EbookGenerator', function() {
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
var tmp = require('tmp');
|
||||
|
||||
var Book = require('../models/book');
|
||||
var createMockFS = require('../fs/mock');
|
||||
var parseBook = require('../parse/parseBook');
|
||||
var generateBook = require('./generateBook');
|
||||
|
||||
var Book = require('../../models/book');
|
||||
var createMockFS = require('../../fs/mock');
|
||||
var parseBook = require('../../parse/parseBook');
|
||||
var generateBook = require('../generateBook');
|
||||
|
||||
/**
|
||||
Generate a book using JSON generator
|
||||
And returns the path to the output dir.
|
||||
|
||||
FOR TESTING PURPOSE ONLY
|
||||
|
||||
@param {Generator}
|
||||
@param {Map<String:String|Map>} files
|
||||
@return {Promise<String>}
|
||||
*/
|
||||
* Generate a book using a generator
|
||||
* And returns the path to the output dir.
|
||||
*
|
||||
* FOR TESTING PURPOSE ONLY
|
||||
*
|
||||
* @param {Generator}
|
||||
* @param {Map<String:String|Map>} files
|
||||
* @return {Promise<String>}
|
||||
*/
|
||||
function generateMock(Generator, files) {
|
||||
var fs = createMockFS(files);
|
||||
var book = Book.createForFS(fs);
|
||||
@@ -1,4 +1,4 @@
|
||||
var generateMock = require('../generateMock');
|
||||
var generateMock = require('./generateMock');
|
||||
var JSONGenerator = require('../json');
|
||||
|
||||
describe('JSONGenerator', function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var fs = require('fs');
|
||||
var generateMock = require('../generateMock');
|
||||
var generateMock = require('./generateMock');
|
||||
var WebsiteGenerator = require('../website');
|
||||
|
||||
describe('WebsiteGenerator', function() {
|
||||
|
||||
+26
-28
@@ -13,13 +13,12 @@ var generateAssets = require('./generateAssets');
|
||||
var generatePages = require('./generatePages');
|
||||
|
||||
/**
|
||||
Process an output to generate the book
|
||||
|
||||
@param {Generator} generator
|
||||
@param {Output} output
|
||||
|
||||
@return {Promise<Output>}
|
||||
*/
|
||||
* Process an output to generate the book
|
||||
*
|
||||
* @param {Generator} generator
|
||||
* @param {Output} output
|
||||
* @return {Promise<Output>}
|
||||
*/
|
||||
function processOutput(generator, startOutput) {
|
||||
return Promise(startOutput)
|
||||
.then(preparePlugins)
|
||||
@@ -133,27 +132,26 @@ function processOutput(generator, startOutput) {
|
||||
}
|
||||
|
||||
/**
|
||||
Generate a book using a generator.
|
||||
|
||||
The overall process is:
|
||||
1. List and load plugins for this book
|
||||
2. Call hook "config"
|
||||
3. Call hook "init"
|
||||
4. Initialize generator
|
||||
5. List all assets and pages
|
||||
6. Copy all assets to output
|
||||
7. Generate all pages
|
||||
8. Call hook "finish:before"
|
||||
9. Finish generation
|
||||
10. Call hook "finish"
|
||||
|
||||
|
||||
@param {Generator} generator
|
||||
@param {Book} book
|
||||
@param {Object} options
|
||||
|
||||
@return {Promise<Output>}
|
||||
*/
|
||||
* Generate a book using a generator.
|
||||
*
|
||||
* The overall process is:
|
||||
* 1. List and load plugins for this book
|
||||
* 2. Call hook "config"
|
||||
* 3. Call hook "init"
|
||||
* 4. Initialize generator
|
||||
* 5. List all assets and pages
|
||||
* 6. Copy all assets to output
|
||||
* 7. Generate all pages
|
||||
* 8. Call hook "finish:before"
|
||||
* 9. Finish generation
|
||||
* 10. Call hook "finish"
|
||||
*
|
||||
*
|
||||
* @param {Generator} generator
|
||||
* @param {Book} book
|
||||
* @param {Object} options
|
||||
* @return {Promise<Output>}
|
||||
*/
|
||||
function generateBook(generator, book, options) {
|
||||
options = generator.Options(options);
|
||||
var state = generator.State? generator.State({}) : Immutable.Map();
|
||||
|
||||
@@ -2,11 +2,11 @@ var Plugins = require('../plugins');
|
||||
var Promise = require('../utils/promise');
|
||||
|
||||
/**
|
||||
Load and setup plugins
|
||||
|
||||
@param {Output}
|
||||
@return {Promise<Output>}
|
||||
*/
|
||||
* Load and setup plugins
|
||||
*
|
||||
* @param {Output}
|
||||
* @return {Promise<Output>}
|
||||
*/
|
||||
function preparePlugins(output) {
|
||||
var book = output.getBook();
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
var createMockOutput = require('../../__tests__/createMock');
|
||||
var prepareI18n = require('../prepareI18n');
|
||||
var createTemplateEngine = require('../createTemplateEngine');
|
||||
|
||||
var WebsiteGenerator = require('../');
|
||||
|
||||
describe('i18n', function() {
|
||||
it('should correctly use english as default language', function() {
|
||||
return createMockOutput(WebsiteGenerator, {
|
||||
'README.md': 'Hello World'
|
||||
})
|
||||
.then(function(output) {
|
||||
return prepareI18n(output);
|
||||
})
|
||||
.then(function(output) {
|
||||
var engine = createTemplateEngine(output, 'README.md');
|
||||
var t = engine.getFilters().get('t');
|
||||
|
||||
expect(t('SUMMARY_INTRODUCTION')).toEqual('Introduction');
|
||||
});
|
||||
});
|
||||
|
||||
it('should correctly use language from book.json', function() {
|
||||
return createMockOutput(WebsiteGenerator, {
|
||||
'README.md': 'Hello World',
|
||||
'book.json': JSON.stringify({ language: 'fr' })
|
||||
})
|
||||
.then(function(output) {
|
||||
return prepareI18n(output);
|
||||
})
|
||||
.then(function(output) {
|
||||
var engine = createTemplateEngine(output, 'README.md');
|
||||
var t = engine.getFilters().get('t');
|
||||
|
||||
expect(t('GITBOOK_LINK')).toEqual('Publié avec GitBook');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -18,19 +18,19 @@ var fileToURL = require('../helper/fileToURL');
|
||||
var resolveFileToURL = require('../helper/resolveFileToURL');
|
||||
|
||||
/**
|
||||
Directory for a theme with the templates
|
||||
*/
|
||||
* Directory for a theme with the templates
|
||||
*/
|
||||
function templateFolder(dir) {
|
||||
return path.join(dir, templatesFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
Create templating engine to render themes
|
||||
|
||||
@param {Output} output
|
||||
@param {String} currentFile
|
||||
@return {TemplateEngine}
|
||||
*/
|
||||
* Create templating engine to render themes
|
||||
*
|
||||
* @param {Output} output
|
||||
* @param {String} currentFile
|
||||
* @return {TemplateEngine}
|
||||
*/
|
||||
function createTemplateEngine(output, currentFile) {
|
||||
var book = output.getBook();
|
||||
var state = output.getState();
|
||||
@@ -47,18 +47,17 @@ function createTemplateEngine(output, currentFile) {
|
||||
var loader = new Templating.ThemesLoader(tplSearchPaths);
|
||||
|
||||
// Get languages
|
||||
var language = config.get('language');
|
||||
var language = config.getValue('language');
|
||||
|
||||
// Create API context
|
||||
var context = Api.encodeGlobal(output);
|
||||
|
||||
|
||||
/**
|
||||
Check if a file exists
|
||||
|
||||
@param {String} fileName
|
||||
@return {Boolean}
|
||||
*/
|
||||
* Check if a file exists
|
||||
* @param {String} fileName
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function fileExists(fileName) {
|
||||
if (!fileName) {
|
||||
return false;
|
||||
@@ -69,11 +68,10 @@ function createTemplateEngine(output, currentFile) {
|
||||
}
|
||||
|
||||
/**
|
||||
Return an article by its path
|
||||
|
||||
@param {String} filePath
|
||||
@return {Object|undefined}
|
||||
*/
|
||||
* Return an article by its path
|
||||
* @param {String} filePath
|
||||
* @return {Object|undefined}
|
||||
*/
|
||||
function getArticleByPath(filePath) {
|
||||
var article = summary.getByPath(filePath);
|
||||
if (!article) return undefined;
|
||||
@@ -82,11 +80,10 @@ function createTemplateEngine(output, currentFile) {
|
||||
}
|
||||
|
||||
/**
|
||||
Return a page by its path
|
||||
|
||||
@param {String} filePath
|
||||
@return {Object|undefined}
|
||||
*/
|
||||
* Return a page by its path
|
||||
* @param {String} filePath
|
||||
* @return {Object|undefined}
|
||||
*/
|
||||
function getPageByPath(filePath) {
|
||||
var page = output.getPage(filePath);
|
||||
if (!page) return undefined;
|
||||
@@ -94,7 +91,6 @@ function createTemplateEngine(output, currentFile) {
|
||||
return JSONUtils.encodePage(page, summary);
|
||||
}
|
||||
|
||||
|
||||
return TemplateEngine.create({
|
||||
loader: loader,
|
||||
|
||||
@@ -108,17 +104,17 @@ function createTemplateEngine(output, currentFile) {
|
||||
|
||||
filters: defaultFilters.merge({
|
||||
/**
|
||||
Translate a sentence
|
||||
*/
|
||||
* Translate a sentence
|
||||
*/
|
||||
t: function t(s) {
|
||||
return i18n.t(language, s);
|
||||
},
|
||||
|
||||
/**
|
||||
Resolve an absolute file path into a
|
||||
relative path.
|
||||
it also resolve pages
|
||||
*/
|
||||
* Resolve an absolute file path into a
|
||||
* relative path.
|
||||
* it also resolve pages
|
||||
*/
|
||||
resolveFile: function(filePath) {
|
||||
filePath = resolveFileToURL(output, filePath);
|
||||
return LocationUtils.relativeForFile(currentFile, filePath);
|
||||
|
||||
@@ -5,11 +5,11 @@ var Promise = require('../../utils/promise');
|
||||
var listSearchPaths = require('./listSearchPaths');
|
||||
|
||||
/**
|
||||
Prepare i18n, load translations from plugins and book
|
||||
|
||||
@param {Output}
|
||||
@return {Promise<Output>}
|
||||
*/
|
||||
* Prepare i18n, load translations from plugins and book
|
||||
*
|
||||
* @param {Output}
|
||||
* @return {Promise<Output>}
|
||||
*/
|
||||
function prepareI18n(output) {
|
||||
var state = output.getState();
|
||||
var i18n = state.getI18n();
|
||||
|
||||
@@ -9,6 +9,7 @@ var direction = require('direction');
|
||||
* @return {Page}
|
||||
*/
|
||||
function parsePageFromString(page, content) {
|
||||
// Parse page YAML
|
||||
var parsed = fm(content);
|
||||
|
||||
return page.merge({
|
||||
|
||||
@@ -11,15 +11,26 @@ var parsePage = require('./parsePage');
|
||||
|
||||
@param {Book} book
|
||||
@param {String} filePath
|
||||
@return {Page}
|
||||
@return {Page?}
|
||||
*/
|
||||
function parseFilePage(book, filePath) {
|
||||
var fs = book.getContentFS();
|
||||
|
||||
return fs.statFile(filePath)
|
||||
.then(function(file) {
|
||||
var page = Page.createForFile(file);
|
||||
return parsePage(book, page);
|
||||
.then(
|
||||
function(file) {
|
||||
var page = Page.createForFile(file);
|
||||
return parsePage(book, page);
|
||||
},
|
||||
function(err) {
|
||||
// file doesn't exist
|
||||
return null;
|
||||
}
|
||||
)
|
||||
.fail(function(err) {
|
||||
var logger = book.getLogger();
|
||||
logger.error.ln('error while parsing page "' + filePath + '":');
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -48,9 +59,12 @@ function parsePagesList(book) {
|
||||
|
||||
return parseFilePage(book, filepath)
|
||||
.then(function(page) {
|
||||
map = map.set(filepath, page);
|
||||
}, function() {
|
||||
// file doesn't exist
|
||||
if (!page) {
|
||||
return;
|
||||
}
|
||||
|
||||
map = map.set(filepath, page);
|
||||
});
|
||||
})
|
||||
)
|
||||
@@ -65,6 +79,11 @@ function parsePagesList(book) {
|
||||
|
||||
return parseFilePage(book, file.getPath())
|
||||
.then(function(page) {
|
||||
// file doesn't exist
|
||||
if (!page) {
|
||||
return;
|
||||
}
|
||||
|
||||
map = map.set(file.getPath(), page);
|
||||
});
|
||||
})
|
||||
|
||||
@@ -4,8 +4,13 @@ var Immutable = require('immutable');
|
||||
* Reduce the difference between a map and its default version
|
||||
* @param {Map} defaultVersion
|
||||
* @param {Map} currentVersion
|
||||
* @return {Map} The properties of currentVersion that differs from defaultVersion
|
||||
*/
|
||||
function reducedObject(defaultVersion, currentVersion) {
|
||||
if(defaultVersion === undefined) {
|
||||
return currentVersion;
|
||||
}
|
||||
|
||||
return currentVersion.reduce(function(result, value, key) {
|
||||
var defaultValue = defaultVersion.get(key);
|
||||
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitbook",
|
||||
"version": "3.2.0-pre.1",
|
||||
"version": "3.2.2",
|
||||
"homepage": "https://www.gitbook.com",
|
||||
"description": "Library and cmd utility to generate GitBooks",
|
||||
"main": "lib/index.js",
|
||||
@@ -22,14 +22,14 @@
|
||||
"fresh-require": "1.0.3",
|
||||
"front-matter": "^2.1.0",
|
||||
"gitbook-asciidoc": "1.2.2",
|
||||
"gitbook-markdown": "2.0.1",
|
||||
"gitbook-markdown": "1.3.2",
|
||||
"gitbook-plugin-fontsettings": "2.0.0",
|
||||
"gitbook-plugin-highlight": "2.0.2",
|
||||
"gitbook-plugin-livereload": "0.0.1",
|
||||
"gitbook-plugin-lunr": "1.2.0",
|
||||
"gitbook-plugin-search": "2.2.1",
|
||||
"gitbook-plugin-sharing": "1.0.2",
|
||||
"gitbook-plugin-theme-default": "1.0.4",
|
||||
"gitbook-plugin-theme-default": "1.0.6",
|
||||
"github-slugid": "1.0.1",
|
||||
"graceful-fs": "4.1.4",
|
||||
"i18n-t": "1.0.1",
|
||||
@@ -44,7 +44,7 @@
|
||||
"moment": "2.13.0",
|
||||
"npm": "3.9.2",
|
||||
"npmi": "2.0.1",
|
||||
"nunjucks": "2.4.2",
|
||||
"nunjucks": "2.5.2",
|
||||
"nunjucks-do": "1.0.0",
|
||||
"object-path": "^0.9.2",
|
||||
"omit-keys": "^0.1.0",
|
||||
|
||||
Reference in New Issue
Block a user