summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamy Pessé <samypesse@gmail.com>2016-04-22 22:21:34 +0200
committerSamy Pessé <samypesse@gmail.com>2016-04-22 22:21:34 +0200
commitfb0ea4610d7835a14c91fd57268ae3d809062f8d (patch)
tree2755a24a10fd30b5f919476eed4fa20a18e440be
parent4f86a9978b4b27b12e40ab0b5b9e18b8e0615266 (diff)
downloadgitbook-fb0ea4610d7835a14c91fd57268ae3d809062f8d.zip
gitbook-fb0ea4610d7835a14c91fd57268ae3d809062f8d.tar.gz
gitbook-fb0ea4610d7835a14c91fd57268ae3d809062f8d.tar.bz2
Add base utils for generation
-rw-r--r--lib/models/__tests__/glossary.js33
-rw-r--r--lib/models/__tests__/glossaryEntry.js17
-rw-r--r--lib/models/generator.js13
-rw-r--r--lib/models/glossaryEntry.js6
-rw-r--r--lib/models/output.js47
-rw-r--r--lib/output/callHook.js15
-rw-r--r--lib/output/generateAssets.js23
-rw-r--r--lib/output/generateBook.js62
-rw-r--r--lib/output/generatePage.js9
-rw-r--r--lib/output/generatePages.js23
-rw-r--r--lib/output/generators/json.js26
-rw-r--r--lib/output/index.js11
-rw-r--r--lib/output/json/index.js6
-rw-r--r--lib/output/json/onPage.js20
-rw-r--r--lib/output/json/options.js8
-rw-r--r--lib/output/prepareAssets.js19
-rw-r--r--lib/output/preparePages.js18
-rw-r--r--lib/output/preparePlugins.js24
-rw-r--r--lib/parse/index.js3
-rw-r--r--lib/parse/listAssets.js24
-rw-r--r--test.js25
21 files changed, 341 insertions, 91 deletions
diff --git a/lib/models/__tests__/glossary.js b/lib/models/__tests__/glossary.js
new file mode 100644
index 0000000..0345627
--- /dev/null
+++ b/lib/models/__tests__/glossary.js
@@ -0,0 +1,33 @@
+jest.autoMockOff();
+
+describe('Glossary', function() {
+ var File = require('../file');
+ var Glossary = require('../glossary');
+ var GlossaryEntry = require('../glossaryEntry');
+
+ describe('createFromEntries', function() {
+ var glossary = Glossary.createFromEntries(File(), [
+ {
+ name: 'Hello World',
+ description: 'Awesome!'
+ },
+ {
+ name: 'JavaScript',
+ description: 'This is a cool language'
+ }
+ ]);
+
+ it('must add all entries', function() {
+ var entries = glossary.getEntries();
+ expect(entries.size).toBe(2);
+ });
+
+ it('must add entries as GlossaryEntries', function() {
+ var entries = glossary.getEntries();
+ var entry = entries.get('hello-world');
+ expect(entry instanceof GlossaryEntry).toBeTruthy();
+ });
+ });
+});
+
+
diff --git a/lib/models/__tests__/glossaryEntry.js b/lib/models/__tests__/glossaryEntry.js
new file mode 100644
index 0000000..9eabc68
--- /dev/null
+++ b/lib/models/__tests__/glossaryEntry.js
@@ -0,0 +1,17 @@
+jest.autoMockOff();
+
+describe('GlossaryEntry', function() {
+ var GlossaryEntry = require('../glossaryEntry');
+
+ describe('getID', function() {
+ it('must return a normalized ID', function() {
+ var entry = new GlossaryEntry({
+ name: 'Hello World'
+ });
+
+ expect(entry.getID()).toBe('hello-world');
+ });
+ });
+});
+
+
diff --git a/lib/models/generator.js b/lib/models/generator.js
deleted file mode 100644
index afc65b1..0000000
--- a/lib/models/generator.js
+++ /dev/null
@@ -1,13 +0,0 @@
-var Immutable = require('immutable');
-
-var Generator = Immutable.Record({
- name: String()
-});
-
-
-
-Generator.create = function(def) {
- return new Generator(def);
-};
-
-module.exports = Generator;
diff --git a/lib/models/glossaryEntry.js b/lib/models/glossaryEntry.js
index 9c390c5..10791db 100644
--- a/lib/models/glossaryEntry.js
+++ b/lib/models/glossaryEntry.js
@@ -1,4 +1,5 @@
var Immutable = require('immutable');
+var slug = require('github-slugid');
/*
A definition represents an entry in the glossary
@@ -35,10 +36,7 @@ GlossaryEntry.prototype.getID = function() {
@return {String}
*/
GlossaryEntry.nameToID = function nameToID(name) {
- return name.toLowerCase()
- .replace(/[\/\\\?\%\*\:\;\|\"\'\\<\\>\#\$\(\)\!\.\@]/g, '')
- .replace(/ /g, '_')
- .trim();
+ return slug(name);
};
diff --git a/lib/models/output.js b/lib/models/output.js
new file mode 100644
index 0000000..957d9d3
--- /dev/null
+++ b/lib/models/output.js
@@ -0,0 +1,47 @@
+var Immutable = require('immutable');
+
+var Book = require('./book');
+
+var Output = Immutable.Record({
+ book: Book(),
+ plugins: Immutable.OrderedMap(),
+ pages: Immutable.OrderedMap(),
+ assets: Immutable.List(),
+ options: Immutable.Map()
+});
+
+Output.prototype.getBook = function() {
+ return this.get('book');
+};
+
+Output.prototype.getPlugins = function() {
+ return this.get('plugins');
+};
+
+Output.prototype.getPages = function() {
+ return this.get('pages');
+};
+
+Output.prototype.getOptions = function() {
+ return this.get('options');
+};
+
+Output.prototype.getAssets = function() {
+ return this.get('assets');
+};
+
+/**
+ Create an Output instance from a book and a set of options
+
+ @param {Book} book
+ @param {Object} options
+ @return {Output}
+*/
+Output.createForBook = function(book, options) {
+ return new Output({
+ book: book,
+ options: options
+ });
+};
+
+module.exports = Output;
diff --git a/lib/output/callHook.js b/lib/output/callHook.js
new file mode 100644
index 0000000..0db1ff1
--- /dev/null
+++ b/lib/output/callHook.js
@@ -0,0 +1,15 @@
+
+/**
+ Call a "global" hook for an output
+
+ @param {String} name
+ @param {Output} output
+ @return {Promise<Output>}
+*/
+function callHook(name, output) {
+
+}
+
+
+
+module.exports = callHook;
diff --git a/lib/output/generateAssets.js b/lib/output/generateAssets.js
new file mode 100644
index 0000000..04ca05d
--- /dev/null
+++ b/lib/output/generateAssets.js
@@ -0,0 +1,23 @@
+var Promise = require('../utils/promise');
+
+/**
+ Output all assets using a generator
+
+ @param {Generator} generator
+ @param {Output} output
+ @return {Promise<Output>}
+*/
+function generateAssets(generator, output) {
+ var assets = output.getAssets();
+
+ // Is generator ignoring assets?
+ if (!generator.onAsset) {
+ return Promise(output);
+ }
+
+ return Promise.reduce(assets, function(out, assetFile) {
+ return generator.onAsset(out, assetFile);
+ }, output);
+}
+
+module.exports = generateAssets;
diff --git a/lib/output/generateBook.js b/lib/output/generateBook.js
index 3f04875..fb03418 100644
--- a/lib/output/generateBook.js
+++ b/lib/output/generateBook.js
@@ -1,42 +1,46 @@
-var Parse = require('../parse');
+var Output = require('../models/output');
+var Promise = require('../utils/promise');
-/**
- List all assets for a book
+var callHook = require('./callHook');
+var preparePlugins = require('./preparePlugins');
+var preparePages = require('./preparePages');
+var prepareAssets = require('./prepareAssets');
+var generateAssets = require('./generateAssets');
+var generatePages = require('./generatePages');
- @param {Book} book
- @param {Map<String:Page>} pages
- @param
-*/
-function listAssets(book, pages) {
- var fs = book.getContentFS();
-
- return fs.listAllFiles()
- .then(function(files) {
- return files.filterNot(function(file) {
- return (
- book.isContentFileIgnored(file) ||
- pages.has(file)
- );
- });
- });
-}
+/**
+ 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"
-/**
- Generate a book using a generator
@param {Generator} generator
@param {Book} book
+ @param {Object} options
@return {Promise}
*/
-function generateBook(generator, book) {
- // List all parsable pages
- return Parse.parsePagesList(book)
- .then(function(pages) {
- return listAssets(book, pages);
- });
+function generateBook(generator, book, options) {
+ options = generator.Options(options);
+
+ return Promise(
+ Output.createForBook(book, options)
+ )
+ .then(preparePlugins)
+ .then(preparePages)
+ .then(prepareAssets)
+ .then(generateAssets.bind(null, generator))
+ .then(generatePages.bind(null, generator));
}
-
module.exports = generateBook;
diff --git a/lib/output/generatePage.js b/lib/output/generatePage.js
deleted file mode 100644
index 9afb50a..0000000
--- a/lib/output/generatePage.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- Generate a page using a generator
-*/
-function generatePage(generator, book, page) {
-
-}
-
-
-module.exports = generatePage;
diff --git a/lib/output/generatePages.js b/lib/output/generatePages.js
new file mode 100644
index 0000000..406f242
--- /dev/null
+++ b/lib/output/generatePages.js
@@ -0,0 +1,23 @@
+var Promise = require('../utils/promise');
+
+/**
+ Output all pages using a generator
+
+ @param {Generator} generator
+ @param {Output} output
+ @return {Promise<Output>}
+*/
+function generatePages(generator, output) {
+ var pages = output.getPages();
+
+ // Is generator ignoring assets?
+ if (!generator.onPage) {
+ return Promise(output);
+ }
+
+ return Promise.reduce(pages, function(out, assetFile) {
+ return generator.onPage(out, assetFile);
+ }, output);
+}
+
+module.exports = generatePages;
diff --git a/lib/output/generators/json.js b/lib/output/generators/json.js
deleted file mode 100644
index e75ae7c..0000000
--- a/lib/output/generators/json.js
+++ /dev/null
@@ -1,26 +0,0 @@
-var Promise = require('../../utils/promise');
-
-var Modifier = require('../');
-
-
-function JSONGenerator(book) {
- this.book = book;
-}
-
-
-JSONGenerator.prototype.onPage = function(page) {
- return Modifier.HTMLTransformations(page, [
- Modifier.svgToImg(),
- Modifier.svgToPng()
- ])
- .then(function() {
-
-
- });
-};
-
-JSONGenerator.prototype.onAsset = function(file) {
-
-};
-
-module.exports = JSONGenerator; \ No newline at end of file
diff --git a/lib/output/index.js b/lib/output/index.js
index 67ca5ee..45bdf65 100644
--- a/lib/output/index.js
+++ b/lib/output/index.js
@@ -1,11 +1,4 @@
-
-
-function generate(book, output) {
-
-}
-
-
-
module.exports = {
- generate: generate
+ generate: require('./generateBook'),
+ JSONGenerator: require('./json')
};
diff --git a/lib/output/json/index.js b/lib/output/json/index.js
new file mode 100644
index 0000000..f721d22
--- /dev/null
+++ b/lib/output/json/index.js
@@ -0,0 +1,6 @@
+
+
+module.exports = {
+ Options: require('./options'),
+ onPage: require('./onPage')
+};
diff --git a/lib/output/json/onPage.js b/lib/output/json/onPage.js
new file mode 100644
index 0000000..3ef5c74
--- /dev/null
+++ b/lib/output/json/onPage.js
@@ -0,0 +1,20 @@
+var Modifier = require('../modifier');
+
+/**
+ Write a page as a json file
+
+ @param {Output} output
+ @param {Page} page
+*/
+function onPage(output, page) {
+ var options = output.
+
+ return Modifier.applyHTMLTransformations(page, [
+ Modifier.HTML.resolveLinks()
+ ])
+ .then(function(newPage) {
+
+ });
+}
+
+module.exports = onPage;
diff --git a/lib/output/json/options.js b/lib/output/json/options.js
new file mode 100644
index 0000000..79167b1
--- /dev/null
+++ b/lib/output/json/options.js
@@ -0,0 +1,8 @@
+var Immutable = require('immutable');
+
+var Options = Immutable.Record({
+ // Root folder for the output
+ root: String()
+});
+
+module.exports = Options;
diff --git a/lib/output/prepareAssets.js b/lib/output/prepareAssets.js
new file mode 100644
index 0000000..19aabef
--- /dev/null
+++ b/lib/output/prepareAssets.js
@@ -0,0 +1,19 @@
+var Parse = require('../parse');
+
+/**
+ List all assets in the book
+
+ @param {Output}
+ @return {Promise<Output>}
+*/
+function prepareAssets(output) {
+ var book = output.getBook();
+ var pages = output.getPages();
+
+ return Parse.listAssets(book, pages)
+ .then(function(assets) {
+ return output.set('assets', assets);
+ });
+}
+
+module.exports = prepareAssets;
diff --git a/lib/output/preparePages.js b/lib/output/preparePages.js
new file mode 100644
index 0000000..396edde
--- /dev/null
+++ b/lib/output/preparePages.js
@@ -0,0 +1,18 @@
+var Parse = require('../parse');
+
+/**
+ List and prepare all pages
+
+ @param {Output}
+ @return {Promise<Output>}
+*/
+function preparePages(output) {
+ var book = output.getBook();
+
+ return Parse.parsePagesList(book)
+ .then(function(pages) {
+ return output.set('pages', pages);
+ });
+}
+
+module.exports = preparePages;
diff --git a/lib/output/preparePlugins.js b/lib/output/preparePlugins.js
new file mode 100644
index 0000000..5768e68
--- /dev/null
+++ b/lib/output/preparePlugins.js
@@ -0,0 +1,24 @@
+var Plugins = require('../plugins');
+
+/**
+ Load and setup plugins
+
+ @param {Output}
+ @return {Promise<Output>}
+*/
+function preparePlugins(output) {
+ var book = output.getBook();
+
+ return Plugins.loadForBook(book)
+ .then(function(plugins) {
+ return Plugins.validateConfig(book, plugins)
+ .then(function(newBook) {
+ return output.merge({
+ book: newBook,
+ plugins: plugins
+ });
+ });
+ });
+}
+
+module.exports = preparePlugins;
diff --git a/lib/parse/index.js b/lib/parse/index.js
index 042024b..58561fb 100644
--- a/lib/parse/index.js
+++ b/lib/parse/index.js
@@ -6,5 +6,6 @@ module.exports = {
parseReadme: require('./parseReadme'),
parseConfig: require('./parseConfig'),
parsePagesList: require('./parsePagesList'),
- parseIgnore: require('./parseIgnore')
+ parseIgnore: require('./parseIgnore'),
+ listAssets: require('./listAssets')
};
diff --git a/lib/parse/listAssets.js b/lib/parse/listAssets.js
new file mode 100644
index 0000000..6159eda
--- /dev/null
+++ b/lib/parse/listAssets.js
@@ -0,0 +1,24 @@
+
+/**
+ List all assets in a book
+ Assets are file not ignored and not a page
+
+ @param {Book} book
+ @param {List<String>} pages
+ @param
+*/
+function listAssets(book, pages) {
+ var fs = book.getContentFS();
+
+ return fs.listAllFiles()
+ .then(function(files) {
+ return files.filterNot(function(file) {
+ return (
+ book.isContentFileIgnored(file) ||
+ pages.has(file)
+ );
+ });
+ });
+}
+
+module.exports = listAssets;
diff --git a/test.js b/test.js
new file mode 100644
index 0000000..8265683
--- /dev/null
+++ b/test.js
@@ -0,0 +1,25 @@
+var path = require('path');
+
+var gitbook = require('./lib');
+var NodeFS = require('./lib/fs/node');
+
+
+var BASE_PATH = path.join(__dirname); //, 'docs');
+
+// Create a filesystem to read the book
+var fs = NodeFS(BASE_PATH);
+
+// Create a book instance
+var book = gitbook.Book.createForFS(fs);
+
+// Parse the book
+gitbook.Parse.parseBook(book)
+.then(function(_book) {
+ return gitbook.Parse.parsePagesList(_book);
+})
+.then(function(pages) {
+ //console.log('parsed', pages);
+}, function(err) {
+ console.log('error:', err.stack);
+});
+