diff options
Diffstat (limited to 'packages/gitbook')
195 files changed, 2603 insertions, 1880 deletions
diff --git a/packages/gitbook/package.json b/packages/gitbook/package.json index 0e85179..f84ed68 100644 --- a/packages/gitbook/package.json +++ b/packages/gitbook/package.json @@ -6,6 +6,7 @@ "main": "lib/index.js", "browser": "./lib/browser.js", "dependencies": { + "asciidoctor.js": "^1.5.5-4", "bash-color": "0.0.4", "cheerio": "0.20.0", "chokidar": "1.5.0", @@ -21,9 +22,7 @@ "extend": "^3.0.0", "fresh-require": "1.0.3", "front-matter": "^2.1.0", - "gitbook-asciidoc": "1.2.2", "gitbook-core": "4.0.0", - "gitbook-markdown": "1.3.2", "gitbook-plugin-copy-code": "4.0.0", "gitbook-plugin-headings": "4.0.0", "gitbook-plugin-highlight": "4.0.0", @@ -44,6 +43,7 @@ "json-schema-defaults": "0.1.1", "jsonschema": "1.1.0", "juice": "2.0.0", + "markup-it": "3.3.0", "mkdirp": "0.5.1", "moment": "2.13.0", "npm": "3.10.9", @@ -59,13 +59,24 @@ "rmdir": "1.2.0", "semver": "5.1.0", "send": "0.13.2", + "slate": "^0.16.8", "spawn-cmd": "0.0.2", "tiny-lr": "0.2.1", "tmp": "0.0.28", "urijs": "1.18.0" }, + "devDependencies": { + "babel-cli": "^6.18.0", + "babel-preset-es2015": "^6.18.0", + "babel-preset-react": "^6.16.0", + "babel-preset-stage-2": "^6.18.0", + "babel-register": "^6.18.0", + "expect": "^1.20.2", + "mocha": "^3.2.0", + "read-metadata": "^1.0.0" + }, "scripts": { - "test": "./node_modules/.bin/mocha ./testing/setup.js \"./src/**/*/__tests__/*.js\" --bail --reporter=list --timeout=100000 --compilers js:babel-register", + "test": "mocha ./testing/setup.js \"./src/**/*/__tests__/*.js\" --bail --reporter=list --timeout=100000 --compilers js:babel-register", "dist": "rm -rf lib/ && babel -d lib/ src/ --source-maps --ignore \"**/*/__tests__/*.js\"", "prepublish": "npm run dist" }, @@ -95,13 +106,5 @@ "name": "Samy Pessé", "email": "samy@gitbook.com" } - ], - "devDependencies": { - "babel-cli": "^6.14.0", - "babel-preset-es2015": "^6.14.0", - "babel-preset-react": "^6.11.1", - "babel-preset-stage-2": "^6.13.0", - "babel-register": "^6.14.0", - "mocha": "^3.0.2" - } + ] } diff --git a/packages/gitbook/src/__tests__/gitbook.js b/packages/gitbook/src/__tests__/gitbook.js index 5292e01..a8390a7 100644 --- a/packages/gitbook/src/__tests__/gitbook.js +++ b/packages/gitbook/src/__tests__/gitbook.js @@ -1,8 +1,8 @@ const gitbook = require('../gitbook'); -describe('satisfies', function() { +describe('satisfies', () => { - it('should return true for *', function() { + it('should return true for *', () => { expect(gitbook.satisfies('*')).toBe(true); }); diff --git a/packages/gitbook/src/__tests__/init.js b/packages/gitbook/src/__tests__/init.js index d8e5398..39313db 100644 --- a/packages/gitbook/src/__tests__/init.js +++ b/packages/gitbook/src/__tests__/init.js @@ -1,13 +1,13 @@ const tmp = require('tmp'); const initBook = require('../init'); -describe('initBook', function() { +describe('initBook', () => { - it('should create a README and SUMMARY for empty book', function() { + it('should create a README and SUMMARY for empty book', () => { const dir = tmp.dirSync(); return initBook(dir.name) - .then(function() { + .then(() => { expect(dir.name).toHaveFile('README.md'); expect(dir.name).toHaveFile('SUMMARY.md'); }); diff --git a/packages/gitbook/src/__tests__/module.js b/packages/gitbook/src/__tests__/module.js index d9220f5..559c919 100644 --- a/packages/gitbook/src/__tests__/module.js +++ b/packages/gitbook/src/__tests__/module.js @@ -1,6 +1,6 @@ -describe('GitBook', function() { - it('should correctly export', function() { +describe('GitBook', () => { + it('should correctly export', () => { require('../'); }); }); diff --git a/packages/gitbook/src/api/encodeGlobal.js b/packages/gitbook/src/api/encodeGlobal.js index 89db629..ca06988 100644 --- a/packages/gitbook/src/api/encodeGlobal.js +++ b/packages/gitbook/src/api/encodeGlobal.js @@ -186,7 +186,7 @@ function encodeGlobal(output) { */ hasFile(fileName, content) { return Promise() - .then(function() { + .then(() => { const filePath = PathUtils.resolveInRoot(outputFolder, fileName); return fs.exists(filePath); @@ -203,11 +203,11 @@ function encodeGlobal(output) { */ writeFile(fileName, content) { return Promise() - .then(function() { + .then(() => { const filePath = PathUtils.resolveInRoot(outputFolder, fileName); return fs.ensureFile(filePath) - .then(function() { + .then(() => { return fs.writeFile(filePath, content); }); }); @@ -224,11 +224,11 @@ function encodeGlobal(output) { */ copyFile(inputFile, outputFile, content) { return Promise() - .then(function() { + .then(() => { const outputFilePath = PathUtils.resolveInRoot(outputFolder, outputFile); return fs.ensureFile(outputFilePath) - .then(function() { + .then(() => { return fs.copy(inputFile, outputFilePath); }); }); @@ -248,7 +248,7 @@ function encodeGlobal(output) { deprecate.field(output, 'this.generator', result, 'generator', output.getGenerator(), '"this.generator" property is deprecated, use "this.output.name" instead'); - deprecate.field(output, 'this.navigation', result, 'navigation', function() { + deprecate.field(output, 'this.navigation', result, 'navigation', () => { return encodeNavigation(output); }, '"navigation" property is deprecated'); diff --git a/packages/gitbook/src/api/encodeNavigation.js b/packages/gitbook/src/api/encodeNavigation.js index 95ab8e3..fc8af91 100644 --- a/packages/gitbook/src/api/encodeNavigation.js +++ b/packages/gitbook/src/api/encodeNavigation.js @@ -33,7 +33,7 @@ function encodeNavigation(output) { const navigation = articles - .map(function(article, i) { + .map((article, i) => { const ref = article.getRef(); if (!ref) { return undefined; @@ -54,7 +54,7 @@ function encodeNavigation(output) { } ]; }) - .filter(function(e) { + .filter((e) => { return Boolean(e); }); diff --git a/packages/gitbook/src/api/encodePage.js b/packages/gitbook/src/api/encodePage.js index 7d563cd..89daccb 100644 --- a/packages/gitbook/src/api/encodePage.js +++ b/packages/gitbook/src/api/encodePage.js @@ -28,7 +28,7 @@ function encodePage(output, page) { return result; }; - deprecate.field(output, 'page.progress', result, 'progress', function() { + deprecate.field(output, 'page.progress', result, 'progress', () => { return encodeProgress(output, page); }, '"page.progress" property is deprecated'); diff --git a/packages/gitbook/src/api/encodeProgress.js b/packages/gitbook/src/api/encodeProgress.js index 3224370..330daf0 100644 --- a/packages/gitbook/src/api/encodeProgress.js +++ b/packages/gitbook/src/api/encodeProgress.js @@ -18,15 +18,15 @@ function encodeProgress(output, page) { let done = true; const chapters = navigation - .map(function(nav, chapterPath) { + .map((nav, chapterPath) => { nav.path = chapterPath; return nav; }) .valueSeq() - .sortBy(function(nav) { + .sortBy((nav) => { return nav.index; }) - .map(function(nav, i) { + .map((nav, i) => { // Calcul percent nav.percent = (i * 100) / Math.max((n - 1), 1); diff --git a/packages/gitbook/src/api/encodeSummary.js b/packages/gitbook/src/api/encodeSummary.js index 323f5d4..63ee15c 100644 --- a/packages/gitbook/src/api/encodeSummary.js +++ b/packages/gitbook/src/api/encodeSummary.js @@ -16,7 +16,7 @@ function encodeSummary(output, summary) { @param {Function} iter */ walk(iter) { - summary.getArticle(function(article) { + summary.getArticle((article) => { const jsonArticle = encodeSummaryArticle(article, false); return iter(jsonArticle); diff --git a/packages/gitbook/src/browser/loadPlugins.js b/packages/gitbook/src/browser/loadPlugins.js index c9bf7a6..3cc0f88 100644 --- a/packages/gitbook/src/browser/loadPlugins.js +++ b/packages/gitbook/src/browser/loadPlugins.js @@ -15,7 +15,7 @@ function loadPlugins(plugins, type) { return plugins .valueSeq() .filter(plugin => plugin.getPackage().has(type)) - .map(plugin => { + .map((plugin) => { const browserFile = path.resolve( plugin.getPath(), plugin.getPackage().get(type) diff --git a/packages/gitbook/src/browser/render.js b/packages/gitbook/src/browser/render.js index 86c3dff..28adf31 100644 --- a/packages/gitbook/src/browser/render.js +++ b/packages/gitbook/src/browser/render.js @@ -18,7 +18,7 @@ function HTML({head, innerHTML, payload, scripts, bootstrap}) { </head> <body> <div id="content" dangerouslySetInnerHTML={{__html: innerHTML}} /> - {scripts.map(script => { + {scripts.map((script) => { return <script key={script} src={script} />; })} <script type="application/payload+json" dangerouslySetInnerHTML={{__html: payload}} /> @@ -67,7 +67,7 @@ function render(plugins, initialState, type, role) { const scripts = plugins.toList() .filter(plugin => plugin.getPackage().has(type)) - .map(plugin => { + .map((plugin) => { return currentFile.relative('gitbook/plugins/' + plugin.getName() + '.js'); }) .toArray(); diff --git a/packages/gitbook/src/cli/build.js b/packages/gitbook/src/cli/build.js index 3f5c937..1816326 100644 --- a/packages/gitbook/src/cli/build.js +++ b/packages/gitbook/src/cli/build.js @@ -22,12 +22,12 @@ module.exports = { const Generator = Output.getGenerator(kwargs.format); return Parse.parseBook(book) - .then(function(resultBook) { + .then((resultBook) => { return Output.generate(Generator, resultBook, { root: outputFolder }); }) - .fin(function() { + .fin(() => { if (kwargs.timing) timing.dump(book.getLogger()); }); } diff --git a/packages/gitbook/src/cli/buildEbook.js b/packages/gitbook/src/cli/buildEbook.js index 56e63f8..5f941ec 100644 --- a/packages/gitbook/src/cli/buildEbook.js +++ b/packages/gitbook/src/cli/buildEbook.js @@ -31,7 +31,7 @@ module.exports = function(format) { const Generator = Output.getGenerator('ebook'); return Parse.parseBook(book) - .then(function(resultBook) { + .then((resultBook) => { return Output.generate(Generator, resultBook, { root: outputFolder, format @@ -39,12 +39,12 @@ module.exports = function(format) { }) // Extract ebook file - .then(function(output) { + .then((output) => { const book = output.getBook(); const languages = book.getLanguages(); if (book.isMultilingual()) { - return Promise.forEach(languages.getList(), function(lang) { + return Promise.forEach(languages.getList(), (lang) => { const langID = lang.getID(); const langOutputFile = path.join( @@ -67,7 +67,7 @@ module.exports = function(format) { }) // Log end - .then(function(count) { + .then((count) => { logger.info.ok(count + ' file(s) generated'); logger.debug('cleaning up... '); diff --git a/packages/gitbook/src/cli/install.js b/packages/gitbook/src/cli/install.js index 6af4013..2e8d110 100644 --- a/packages/gitbook/src/cli/install.js +++ b/packages/gitbook/src/cli/install.js @@ -14,7 +14,7 @@ module.exports = { const book = getBook(args, kwargs); return Parse.parseConfig(book) - .then(function(resultBook) { + .then((resultBook) => { return Plugins.installPlugins(resultBook); }); } diff --git a/packages/gitbook/src/cli/options.js b/packages/gitbook/src/cli/options.js index d643f91..ac51360 100644 --- a/packages/gitbook/src/cli/options.js +++ b/packages/gitbook/src/cli/options.js @@ -5,7 +5,7 @@ const logOptions = { description: 'Minimum log level to display', values: Logger.LEVELS .keySeq() - .map(function(s) { + .map((s) => { return s.toLowerCase(); }).toJS(), defaults: 'info' diff --git a/packages/gitbook/src/cli/parse.js b/packages/gitbook/src/cli/parse.js index 3d38fe7..a6aee08 100644 --- a/packages/gitbook/src/cli/parse.js +++ b/packages/gitbook/src/cli/parse.js @@ -42,7 +42,7 @@ function printMultingualBook(book) { logger.info.ln(languages.size + ' languages'); - languages.forEach(function(lang) { + languages.forEach((lang) => { logger.info.ln('Language:', lang.getTitle()); printBook(books.get(lang.getID())); logger.info.ln(''); @@ -60,7 +60,7 @@ module.exports = { const logger = book.getLogger(); return Parse.parseBook(book) - .then(function(resultBook) { + .then((resultBook) => { const rootFolder = book.getRoot(); const contentFolder = book.getContentRoot(); diff --git a/packages/gitbook/src/cli/serve.js b/packages/gitbook/src/cli/serve.js index 6397c2e..243af16 100644 --- a/packages/gitbook/src/cli/serve.js +++ b/packages/gitbook/src/cli/serve.js @@ -20,7 +20,7 @@ let server, lrServer, lrPath; function waitForCtrlC() { const d = Promise.defer(); - process.on('SIGINT', function() { + process.on('SIGINT', () => { d.resolve(); }); @@ -43,9 +43,9 @@ function generateBook(args, kwargs) { if (server.isRunning()) console.log('Stopping server'); return server.stop() - .then(function() { + .then(() => { return Parse.parseBook(book) - .then(function(resultBook) { + .then((resultBook) => { if (hasLiveReloading) { // Enable livereload plugin let config = resultBook.getConfig(); @@ -58,12 +58,12 @@ function generateBook(args, kwargs) { }); }); }) - .then(function() { + .then(() => { console.log(); console.log('Starting server ...'); return server.start(outputFolder, port); }) - .then(function() { + .then(() => { console.log('Serving book on http://localhost:' + port); if (lrPath && hasLiveReloading) { @@ -79,13 +79,13 @@ function generateBook(args, kwargs) { open('http://localhost:' + port, browser); } }) - .then(function() { + .then(() => { if (!hasWatch) { return waitForCtrlC(); } return watch(book.getRoot()) - .then(function(filepath) { + .then((filepath) => { // set livereload path lrPath = filepath; console.log('Restart after change in file', filepath); @@ -138,21 +138,21 @@ module.exports = { const hasLiveReloading = kwargs['live']; return Promise() - .then(function() { + .then(() => { if (!hasWatch || !hasLiveReloading) { return; } lrServer = tinylr({}); return Promise.nfcall(lrServer.listen.bind(lrServer), kwargs.lrport) - .then(function() { + .then(() => { console.log('Live reload server started on port:', kwargs.lrport); console.log('Press CTRL+C to quit ...'); console.log(''); }); }) - .then(function() { + .then(() => { return generateBook(args, kwargs); }); } diff --git a/packages/gitbook/src/cli/server.js b/packages/gitbook/src/cli/server.js index c494efc..930e5c0 100644 --- a/packages/gitbook/src/cli/server.js +++ b/packages/gitbook/src/cli/server.js @@ -31,7 +31,7 @@ class Server extends events.EventEmitter { if (!this.isRunning()) return Promise(); const d = Promise.defer(); - this.running.close(function(err) { + this.running.close((err) => { that.running = null; that.emit('state', false); @@ -57,10 +57,10 @@ class Server extends events.EventEmitter { if (that.isRunning()) pre = this.stop(); return pre - .then(function() { + .then(() => { const d = Promise.defer(); - that.running = http.createServer(function(req, res) { + that.running = http.createServer((req, res) => { // Render error function error(err) { res.statusCode = err.status || 500; @@ -69,7 +69,7 @@ class Server extends events.EventEmitter { // Redirect to directory's index.html function redirect() { - const resultURL = urlTransform(req.url, function(parsed) { + const resultURL = urlTransform(req.url, (parsed) => { parsed.pathname += '/'; return parsed; }); @@ -90,15 +90,15 @@ class Server extends events.EventEmitter { .pipe(res); }); - that.running.on('connection', function(socket) { + that.running.on('connection', (socket) => { that.sockets.push(socket); socket.setTimeout(4000); - socket.on('close', function() { + socket.on('close', () => { that.sockets.splice(that.sockets.indexOf(socket), 1); }); }); - that.running.listen(port, function(err) { + that.running.listen(port, (err) => { if (err) return d.reject(err); that.port = port; diff --git a/packages/gitbook/src/cli/watch.js b/packages/gitbook/src/cli/watch.js index e1d453c..9571ef5 100644 --- a/packages/gitbook/src/cli/watch.js +++ b/packages/gitbook/src/cli/watch.js @@ -2,14 +2,14 @@ const path = require('path'); const chokidar = require('chokidar'); const Promise = require('../utils/promise'); -const parsers = require('../parsers'); +const { FILE_EXTENSIONS } = require('../parsers'); /** - Watch a folder and resolve promise once a file is modified - - @param {String} dir - @return {Promise} -*/ + * Watch a folder and resolve promise once a file is modified + * + * @param {String} dir + * @return {Promise} + */ function watch(dir) { const d = Promise.defer(); dir = path.resolve(dir); @@ -19,7 +19,7 @@ function watch(dir) { ]; // Watch all parsable files - parsers.extensions.forEach(function(ext) { + FILE_EXTENSIONS.forEach((ext) => { toWatch.push('**/*' + ext); }); @@ -29,12 +29,12 @@ function watch(dir) { ignoreInitial: true }); - watcher.once('all', function(e, filepath) { + watcher.once('all', (e, filepath) => { watcher.close(); d.resolve(filepath); }); - watcher.once('error', function(err) { + watcher.once('error', (err) => { watcher.close(); d.reject(err); diff --git a/packages/gitbook/src/constants/__tests__/configSchema.js b/packages/gitbook/src/constants/__tests__/configSchema.js index df83680..5c7014f 100644 --- a/packages/gitbook/src/constants/__tests__/configSchema.js +++ b/packages/gitbook/src/constants/__tests__/configSchema.js @@ -1,7 +1,7 @@ const jsonschema = require('jsonschema'); const schema = require('../configSchema'); -describe('configSchema', function() { +describe('configSchema', () => { function validate(cfg) { const v = new jsonschema.Validator(); @@ -10,9 +10,9 @@ describe('configSchema', function() { }); } - describe('structure', function() { + describe('structure', () => { - it('should accept dot in filename', function() { + it('should accept dot in filename', () => { const result = validate({ structure: { readme: 'book-intro.adoc' @@ -22,7 +22,7 @@ describe('configSchema', function() { expect(result.errors.length).toBe(0); }); - it('should accept uppercase in filename', function() { + it('should accept uppercase in filename', () => { const result = validate({ structure: { readme: 'BOOK.adoc' @@ -32,7 +32,7 @@ describe('configSchema', function() { expect(result.errors.length).toBe(0); }); - it('should not accept filepath', function() { + it('should not accept filepath', () => { const result = validate({ structure: { readme: 'folder/myFile.md' diff --git a/packages/gitbook/src/fs/__tests__/mock.js b/packages/gitbook/src/fs/__tests__/mock.js index 7d1ea48..de875d4 100644 --- a/packages/gitbook/src/fs/__tests__/mock.js +++ b/packages/gitbook/src/fs/__tests__/mock.js @@ -1,6 +1,6 @@ const createMockFS = require('../mock'); -describe('MockFS', function() { +describe('MockFS', () => { const fs = createMockFS({ 'README.md': 'Hello World', 'SUMMARY.md': '# Summary', @@ -13,63 +13,63 @@ describe('MockFS', function() { } }); - describe('exists', function() { - it('must return true for a file', function() { + describe('exists', () => { + it('must return true for a file', () => { return fs.exists('README.md') - .then(function(result) { + .then((result) => { expect(result).toBeTruthy(); }); }); - it('must return false for a non existing file', function() { + it('must return false for a non existing file', () => { return fs.exists('README_NOTEXISTS.md') - .then(function(result) { + .then((result) => { expect(result).toBeFalsy(); }); }); - it('must return true for a directory', function() { + it('must return true for a directory', () => { return fs.exists('folder') - .then(function(result) { + .then((result) => { expect(result).toBeTruthy(); }); }); - it('must return true for a deep file', function() { + it('must return true for a deep file', () => { return fs.exists('folder/test.md') - .then(function(result) { + .then((result) => { expect(result).toBeTruthy(); }); }); - it('must return true for a deep file (2)', function() { + it('must return true for a deep file (2)', () => { return fs.exists('folder/folder2/hello.md') - .then(function(result) { + .then((result) => { expect(result).toBeTruthy(); }); }); }); - describe('readAsString', function() { - it('must return content for a file', function() { + describe('readAsString', () => { + it('must return content for a file', () => { return fs.readAsString('README.md') - .then(function(result) { + .then((result) => { expect(result).toBe('Hello World'); }); }); - it('must return content for a deep file', function() { + it('must return content for a deep file', () => { return fs.readAsString('folder/test.md') - .then(function(result) { + .then((result) => { expect(result).toBe('Cool'); }); }); }); - describe('readDir', function() { - it('must return content for a directory', function() { + describe('readDir', () => { + it('must return content for a directory', () => { return fs.readDir('./') - .then(function(files) { + .then((files) => { expect(files.size).toBe(3); expect(files.includes('README.md')).toBeTruthy(); expect(files.includes('SUMMARY.md')).toBeTruthy(); diff --git a/packages/gitbook/src/fs/mock.js b/packages/gitbook/src/fs/mock.js index 611b2ab..733cd35 100644 --- a/packages/gitbook/src/fs/mock.js +++ b/packages/gitbook/src/fs/mock.js @@ -17,7 +17,7 @@ function createMockFS(files, root = '') { function getFile(filePath) { const parts = path.normalize(filePath).split(path.sep); - return parts.reduce(function(list, part, i) { + return parts.reduce((list, part, i) => { if (!list) return null; let file; @@ -73,7 +73,7 @@ function createMockFS(files, root = '') { } return dir - .map(function(content, name) { + .map((content, name) => { if (!is.string(content)) { name = name + '/'; } diff --git a/packages/gitbook/src/fs/node.js b/packages/gitbook/src/fs/node.js index 6e28daf..3cb84a7 100644 --- a/packages/gitbook/src/fs/node.js +++ b/packages/gitbook/src/fs/node.js @@ -7,18 +7,18 @@ const FS = require('../models/fs'); function fsReadDir(folder) { return fs.readdir(folder) - .then(function(files) { + .then((files) => { files = Immutable.List(files); return files - .map(function(file) { + .map((file) => { if (file == '.' || file == '..') return; const stat = fs.statSync(path.join(folder, file)); if (stat.isDirectory()) file = file + path.sep; return file; }) - .filter(function(file) { + .filter((file) => { return Boolean(file); }); }); diff --git a/packages/gitbook/src/init.js b/packages/gitbook/src/init.js index bbd5f90..d9912e0 100644 --- a/packages/gitbook/src/init.js +++ b/packages/gitbook/src/init.js @@ -7,37 +7,38 @@ const File = require('./models/file'); const Readme = require('./models/readme'); const Book = require('./models/book'); const Parse = require('./parse'); +const SummaryModifier = require('./modifiers/summary'); /** - Initialize folder structure for a book - Read SUMMARY to created the right chapter - - @param {Book} - @param {String} - @return {Promise} -*/ + * Initialize folder structure for a book + * Read SUMMARY to created the right chapter + * + * @param {Book} + * @param {String} + * @return {Promise} + */ function initBook(rootFolder) { const extension = '.md'; return fs.mkdirp(rootFolder) // Parse the summary and readme - .then(function() { + .then(() => { const bookFS = createNodeFS(rootFolder); const book = Book.createForFS(bookFS); return Parse.parseReadme(book) // Setup default readme if doesn't found one - .fail(function() { + .fail(() => { const readmeFile = File.createWithFilepath('README' + extension); - const readme = Readme.create(readmeFile); + const readme = Readme.create().setFile(readmeFile); return book.setReadme(readme); }); }) - .then(Parse.parseSummary) + .then(book => Parse.parseSummary(book)) - .then(function(book) { + .then((book) => { const logger = book.getLogger(); const summary = book.getSummary(); const summaryFile = summary.getFile(); @@ -46,16 +47,16 @@ function initBook(rootFolder) { const articles = summary.getArticlesAsList(); // Write pages - return Promise.forEach(articles, function(article) { + return Promise.forEach(articles, (article) => { const articlePath = article.getPath(); const filePath = articlePath ? path.join(rootFolder, articlePath) : null; if (!filePath) { return; } - return fs.assertFile(filePath, function() { + return fs.assertFile(filePath, () => { return fs.ensureFile(filePath) - .then(function() { + .then(() => { logger.info.ln('create', article.getPath()); return fs.writeFile(filePath, '# ' + article.getTitle() + '\n\n'); }); @@ -63,18 +64,19 @@ function initBook(rootFolder) { }) // Write summary - .then(function() { + .then(() => { const filePath = path.join(rootFolder, summaryFilename); return fs.ensureFile(filePath) - .then(function() { + .then(() => { logger.info.ln('create ' + path.basename(filePath)); - return fs.writeFile(filePath, summary.toText(extension)); + const text = SummaryModifier.toText(summary, extension); + return fs.writeFile(filePath, text); }); }) // Log end - .then(function() { + .then(() => { logger.info.ln('initialization is finished'); }); }); diff --git a/packages/gitbook/src/json/encodeLanguages.js b/packages/gitbook/src/json/encodeLanguages.js index 809cfb2..6f866b8 100644 --- a/packages/gitbook/src/json/encodeLanguages.js +++ b/packages/gitbook/src/json/encodeLanguages.js @@ -17,7 +17,7 @@ function encodeLanguages(languages, currentLanguage, urls) { current: currentLanguage, list: list .valueSeq() - .map(function(lang) { + .map((lang) => { return { id: lang.getID(), title: lang.getTitle() diff --git a/packages/gitbook/src/models/__tests__/config.js b/packages/gitbook/src/models/__tests__/config.js index a865f96..30c0b37 100644 --- a/packages/gitbook/src/models/__tests__/config.js +++ b/packages/gitbook/src/models/__tests__/config.js @@ -1,7 +1,7 @@ const Immutable = require('immutable'); const Config = require('../config'); -describe('Config', function() { +describe('Config', () => { const config = Config.createWithValues({ hello: { world: 1, @@ -10,30 +10,30 @@ describe('Config', function() { } }); - describe('getValue', function() { - it('must return value as immutable', function() { + describe('getValue', () => { + it('must return value as immutable', () => { const value = config.getValue('hello'); expect(Immutable.Map.isMap(value)).toBeTruthy(); }); - it('must return deep value', function() { + it('must return deep value', () => { const value = config.getValue('hello.world'); expect(value).toBe(1); }); - it('must return default value if non existant', function() { + it('must return default value if non existant', () => { const value = config.getValue('hello.nonExistant', 'defaultValue'); expect(value).toBe('defaultValue'); }); - it('must not return default value for falsy values', function() { + it('must not return default value for falsy values', () => { const value = config.getValue('hello.isFalse', 'defaultValue'); expect(value).toBe(false); }); }); - describe('setValue', function() { - it('must set value as immutable', function() { + describe('setValue', () => { + it('must set value as immutable', () => { const testConfig = config.setValue('hello', { 'cool': 1 }); @@ -44,7 +44,7 @@ describe('Config', function() { expect(value.has('cool')).toBeTruthy(); }); - it('must set deep value', function() { + it('must set deep value', () => { const testConfig = config.setValue('hello.world', 2); const hello = testConfig.getValue('hello'); const world = testConfig.getValue('hello.world'); @@ -56,8 +56,8 @@ describe('Config', function() { }); }); - describe('toReducedVersion', function() { - it('must only return diffs for simple values', function() { + describe('toReducedVersion', () => { + it('must only return diffs for simple values', () => { const _config = Config.createWithValues({ gitbook: '3.0.0' }); @@ -69,7 +69,7 @@ describe('Config', function() { }); }); - it('must only return diffs for deep values', function() { + it('must only return diffs for deep values', () => { const _config = Config.createWithValues({ structure: { readme: 'intro.md' diff --git a/packages/gitbook/src/models/__tests__/glossary.js b/packages/gitbook/src/models/__tests__/glossary.js index b50338a..aa7b9b9 100644 --- a/packages/gitbook/src/models/__tests__/glossary.js +++ b/packages/gitbook/src/models/__tests__/glossary.js @@ -2,8 +2,8 @@ const File = require('../file'); const Glossary = require('../glossary'); const GlossaryEntry = require('../glossaryEntry'); -describe('Glossary', function() { - const glossary = Glossary.createFromEntries(File(), [ +describe('Glossary', () => { + const glossary = Glossary.createFromEntries([ { name: 'Hello World', description: 'Awesome!' @@ -14,26 +14,16 @@ describe('Glossary', function() { } ]); - describe('createFromEntries', function() { - it('must add all entries', function() { + describe('createFromEntries', () => { + it('must add all entries', () => { const entries = glossary.getEntries(); expect(entries.size).toBe(2); }); - it('must add entries as GlossaryEntries', function() { + it('must add entries as GlossaryEntries', () => { const entries = glossary.getEntries(); const entry = entries.get('hello-world'); expect(entry instanceof GlossaryEntry).toBeTruthy(); }); }); - - describe('toText', function() { - it('return as markdown', function() { - return glossary.toText('.md') - .then(function(text) { - expect(text).toContain('# Glossary'); - }); - }); - }); }); - diff --git a/packages/gitbook/src/models/__tests__/glossaryEntry.js b/packages/gitbook/src/models/__tests__/glossaryEntry.js index 66ddab4..af96c58 100644 --- a/packages/gitbook/src/models/__tests__/glossaryEntry.js +++ b/packages/gitbook/src/models/__tests__/glossaryEntry.js @@ -1,14 +1,13 @@ const GlossaryEntry = require('../glossaryEntry'); -describe('GlossaryEntry', function() { - describe('getID', function() { - it('must return a normalized ID', function() { +describe('GlossaryEntry', () => { + describe('getID', () => { + it('must return a normalized ID', () => { const entry = new GlossaryEntry({ name: 'Hello World' }); - expect(entry.getID()).toBe('hello-world'); + expect(entry.id).toBe('hello-world'); }); }); }); - diff --git a/packages/gitbook/src/models/__tests__/page.js b/packages/gitbook/src/models/__tests__/page.js index b004121..047ced6 100644 --- a/packages/gitbook/src/models/__tests__/page.js +++ b/packages/gitbook/src/models/__tests__/page.js @@ -1,10 +1,10 @@ const Immutable = require('immutable'); const Page = require('../page'); -describe('Page', function() { +describe('Page', () => { - describe('toText', function() { - it('must not prepend frontmatter if no attributes', function() { + describe('toText', () => { + it('must not prepend frontmatter if no attributes', () => { const page = (new Page()).merge({ content: 'Hello World' }); @@ -12,7 +12,7 @@ describe('Page', function() { expect(page.toText()).toBe('Hello World'); }); - it('must prepend frontmatter if attributes', function() { + it('must prepend frontmatter if attributes', () => { const page = (new Page()).merge({ content: 'Hello World', attributes: Immutable.fromJS({ diff --git a/packages/gitbook/src/models/__tests__/plugin.js b/packages/gitbook/src/models/__tests__/plugin.js index 63cb58c..13cf1c5 100644 --- a/packages/gitbook/src/models/__tests__/plugin.js +++ b/packages/gitbook/src/models/__tests__/plugin.js @@ -1,22 +1,22 @@ -describe('Plugin', function() { +describe('Plugin', () => { const Plugin = require('../plugin'); - describe('createFromString', function() { - it('must parse name', function() { + describe('createFromString', () => { + it('must parse name', () => { const plugin = Plugin.createFromString('hello'); expect(plugin.getName()).toBe('hello'); expect(plugin.getVersion()).toBe('*'); }); - it('must parse version', function() { + it('must parse version', () => { const plugin = Plugin.createFromString('hello@1.0.0'); expect(plugin.getName()).toBe('hello'); expect(plugin.getVersion()).toBe('1.0.0'); }); }); - describe('isLoaded', function() { - it('must return false for empty plugin', function() { + describe('isLoaded', () => { + it('must return false for empty plugin', () => { const plugin = Plugin.createFromString('hello'); expect(plugin.isLoaded()).toBe(false); }); diff --git a/packages/gitbook/src/models/__tests__/pluginDependency.js b/packages/gitbook/src/models/__tests__/pluginDependency.js index cda0cc2..e17b749 100644 --- a/packages/gitbook/src/models/__tests__/pluginDependency.js +++ b/packages/gitbook/src/models/__tests__/pluginDependency.js @@ -1,50 +1,50 @@ const Immutable = require('immutable'); const PluginDependency = require('../pluginDependency'); -describe('PluginDependency', function() { - describe('createFromString', function() { - it('must parse name', function() { +describe('PluginDependency', () => { + describe('createFromString', () => { + it('must parse name', () => { const plugin = PluginDependency.createFromString('hello'); expect(plugin.getName()).toBe('hello'); expect(plugin.getVersion()).toBe('*'); }); - it('must parse state', function() { + it('must parse state', () => { const plugin = PluginDependency.createFromString('-hello'); expect(plugin.getName()).toBe('hello'); expect(plugin.isEnabled()).toBe(false); }); - describe('Version', function() { - it('must parse version', function() { + describe('Version', () => { + it('must parse version', () => { const plugin = PluginDependency.createFromString('hello@1.0.0'); expect(plugin.getName()).toBe('hello'); expect(plugin.getVersion()).toBe('1.0.0'); }); - it('must parse semver', function() { + it('must parse semver', () => { const plugin = PluginDependency.createFromString('hello@>=4.0.0'); expect(plugin.getName()).toBe('hello'); expect(plugin.getVersion()).toBe('>=4.0.0'); }); }); - describe('GIT Version', function() { - it('must handle HTTPS urls', function() { + describe('GIT Version', () => { + it('must handle HTTPS urls', () => { const plugin = PluginDependency.createFromString('hello@git+https://github.com/GitbookIO/plugin-ga.git'); expect(plugin.getName()).toBe('hello'); expect(plugin.getVersion()).toBe('git+https://github.com/GitbookIO/plugin-ga.git'); }); - it('must handle SSH urls', function() { + it('must handle SSH urls', () => { const plugin = PluginDependency.createFromString('hello@git+ssh://samy@github.com/GitbookIO/plugin-ga.git'); expect(plugin.getName()).toBe('hello'); expect(plugin.getVersion()).toBe('git+ssh://samy@github.com/GitbookIO/plugin-ga.git'); }); }); - describe('listToArray', function() { - it('must create an array from a list of plugin dependencies', function() { + describe('listToArray', () => { + it('must create an array from a list of plugin dependencies', () => { const list = PluginDependency.listToArray(Immutable.List([ PluginDependency.createFromString('hello@1.0.0'), PluginDependency.createFromString('noversion'), @@ -59,8 +59,8 @@ describe('PluginDependency', function() { }); }); - describe('listFromArray', function() { - it('must create an array from a list of plugin dependencies', function() { + describe('listFromArray', () => { + it('must create an array from a list of plugin dependencies', () => { const arr = Immutable.fromJS([ 'hello@1.0.0', { diff --git a/packages/gitbook/src/models/__tests__/summary.js b/packages/gitbook/src/models/__tests__/summary.js index 49ed9b1..39612ea 100644 --- a/packages/gitbook/src/models/__tests__/summary.js +++ b/packages/gitbook/src/models/__tests__/summary.js @@ -1,9 +1,7 @@ +const Summary = require('../summary'); -describe('Summary', function() { - const File = require('../file'); - const Summary = require('../summary'); - - const summary = Summary.createFromParts(File(), [ +describe('Summary', () => { + const summary = Summary.createFromParts([ { articles: [ { @@ -28,22 +26,22 @@ describe('Summary', function() { } ]); - describe('createFromEntries', function() { - it('must add all parts', function() { + describe('createFromEntries', () => { + it('must add all parts', () => { const parts = summary.getParts(); expect(parts.size).toBe(2); }); }); - describe('getByLevel', function() { - it('can return a Part', function() { + describe('getByLevel', () => { + it('can return a Part', () => { const part = summary.getByLevel('1'); expect(part).toBeDefined(); expect(part.getArticles().size).toBe(4); }); - it('can return a Part (2)', function() { + it('can return a Part (2)', () => { const part = summary.getByLevel('2'); expect(part).toBeDefined(); @@ -51,7 +49,7 @@ describe('Summary', function() { expect(part.getArticles().size).toBe(0); }); - it('can return an Article', function() { + it('can return an Article', () => { const article = summary.getByLevel('1.1'); expect(article).toBeDefined(); @@ -59,35 +57,25 @@ describe('Summary', function() { }); }); - describe('getByPath', function() { - it('return correct article', function() { + describe('getByPath', () => { + it('return correct article', () => { const article = summary.getByPath('README.md'); expect(article).toBeDefined(); expect(article.getTitle()).toBe('My First Article'); }); - it('return correct article', function() { + it('return correct article', () => { const article = summary.getByPath('article.md'); expect(article).toBeDefined(); expect(article.getTitle()).toBe('My Second Article'); }); - it('return undefined if not found', function() { + it('return undefined if not found', () => { const article = summary.getByPath('NOT_EXISTING.md'); expect(article).toBeFalsy(); }); }); - - describe('toText', function() { - it('return as markdown', function() { - return summary.toText('.md') - .then(function(text) { - expect(text).toContain('# Summary'); - }); - }); - }); }); - diff --git a/packages/gitbook/src/models/__tests__/summaryArticle.js b/packages/gitbook/src/models/__tests__/summaryArticle.js index 506d481..bddcfda 100644 --- a/packages/gitbook/src/models/__tests__/summaryArticle.js +++ b/packages/gitbook/src/models/__tests__/summaryArticle.js @@ -1,14 +1,14 @@ const SummaryArticle = require('../summaryArticle'); const File = require('../file'); -describe('SummaryArticle', function() { - describe('createChildLevel', function() { - it('must create the right level', function() { +describe('SummaryArticle', () => { + describe('createChildLevel', () => { + it('must create the right level', () => { const article = SummaryArticle.create({}, '1.1'); expect(article.createChildLevel()).toBe('1.1.1'); }); - it('must create the right level when has articles', function() { + it('must create the right level when has articles', () => { const article = SummaryArticle.create({ articles: [ { @@ -20,8 +20,8 @@ describe('SummaryArticle', function() { }); }); - describe('isFile', function() { - it('must return true when exactly the file', function() { + describe('isFile', () => { + it('must return true when exactly the file', () => { const article = SummaryArticle.create({ ref: 'hello.md' }, '1.1'); @@ -30,7 +30,7 @@ describe('SummaryArticle', function() { expect(article.isFile(file)).toBe(true); }); - it('must return true when path is not normalized', function() { + it('must return true when path is not normalized', () => { const article = SummaryArticle.create({ ref: '/hello.md' }, '1.1'); @@ -39,7 +39,7 @@ describe('SummaryArticle', function() { expect(article.isFile(file)).toBe(true); }); - it('must return false when has anchor', function() { + it('must return false when has anchor', () => { const article = SummaryArticle.create({ ref: 'hello.md#world' }, '1.1'); diff --git a/packages/gitbook/src/models/__tests__/summaryPart.js b/packages/gitbook/src/models/__tests__/summaryPart.js index fc9e8b5..a59bd66 100644 --- a/packages/gitbook/src/models/__tests__/summaryPart.js +++ b/packages/gitbook/src/models/__tests__/summaryPart.js @@ -1,13 +1,13 @@ const SummaryPart = require('../summaryPart'); -describe('SummaryPart', function() { - describe('createChildLevel', function() { - it('must create the right level', function() { +describe('SummaryPart', () => { + describe('createChildLevel', () => { + it('must create the right level', () => { const article = SummaryPart.create({}, '1'); expect(article.createChildLevel()).toBe('1.1'); }); - it('must create the right level when has articles', function() { + it('must create the right level when has articles', () => { const article = SummaryPart.create({ articles: [ { diff --git a/packages/gitbook/src/models/__tests__/templateBlock.js b/packages/gitbook/src/models/__tests__/templateBlock.js index 5db8a80..5c7b404 100644 --- a/packages/gitbook/src/models/__tests__/templateBlock.js +++ b/packages/gitbook/src/models/__tests__/templateBlock.js @@ -2,12 +2,12 @@ const nunjucks = require('nunjucks'); const Immutable = require('immutable'); const Promise = require('../../utils/promise'); -describe('TemplateBlock', function() { +describe('TemplateBlock', () => { const TemplateBlock = require('../templateBlock'); - describe('.create', function() { - it('must initialize a simple TemplateBlock from a function', function() { - const templateBlock = TemplateBlock.create('sayhello', function(block) { + describe('.create', () => { + it('must initialize a simple TemplateBlock from a function', () => { + const templateBlock = TemplateBlock.create('sayhello', (block) => { return { message: 'Hello World' }; }); @@ -18,40 +18,40 @@ describe('TemplateBlock', function() { }); }); - describe('.toProps', function() { - it('must handle sync method', function() { - const templateBlock = TemplateBlock.create('sayhello', function(block) { + describe('.toProps', () => { + it('must handle sync method', () => { + const templateBlock = TemplateBlock.create('sayhello', (block) => { return { message: 'Hello World' }; }); return templateBlock.toProps() - .then(function(props) { + .then((props) => { expect(props).toEqual({ message: 'Hello World' }); }); }); - it('must not fail if return a string', function() { - const templateBlock = TemplateBlock.create('sayhello', function(block) { + it('must not fail if return a string', () => { + const templateBlock = TemplateBlock.create('sayhello', (block) => { return 'Hello World'; }); return templateBlock.toProps() - .then(function(props) { + .then((props) => { expect(props).toEqual({ children: 'Hello World' }); }); }); }); - describe('.getShortcuts', function() { - it('must return undefined if no shortcuts', function() { - const templateBlock = TemplateBlock.create('sayhello', function(block) { + describe('.getShortcuts', () => { + it('must return undefined if no shortcuts', () => { + const templateBlock = TemplateBlock.create('sayhello', (block) => { return { message: 'Hello World' }; }); expect(templateBlock.getShortcuts()).toNotExist(); }); - it('.must return complete shortcut', function() { + it('.must return complete shortcut', () => { const templateBlock = TemplateBlock.create('sayhello', { process(block) { return { message: 'Hello World' }; @@ -73,9 +73,9 @@ describe('TemplateBlock', function() { }); }); - describe('.toNunjucksExt()', function() { - it('should render children correctly', function() { - const templateBlock = TemplateBlock.create('sayhello', function(block) { + describe('.toNunjucksExt()', () => { + it('should render children correctly', () => { + const templateBlock = TemplateBlock.create('sayhello', (block) => { return 'Hello'; }); @@ -89,13 +89,13 @@ describe('TemplateBlock', function() { // Render a template using the block const src = '{% sayhello %}{% endsayhello %}'; return Promise.nfcall(env.renderString.bind(env), src) - .then(function(res) { + .then((res) => { expect(res).toBe('<xblock name="sayhello" props="{}">Hello</xblock>'); }); }); - it('must handle HTML children', function() { - const templateBlock = TemplateBlock.create('sayhello', function(block) { + it('must handle HTML children', () => { + const templateBlock = TemplateBlock.create('sayhello', (block) => { return '<p>Hello, World!</p>'; }); @@ -109,13 +109,13 @@ describe('TemplateBlock', function() { // Render a template using the block const src = '{% sayhello %}{% endsayhello %}'; return Promise.nfcall(env.renderString.bind(env), src) - .then(function(res) { + .then((res) => { expect(res).toBe('<xblock name="sayhello" props="{}"><p>Hello, World!</p></xblock>'); }); }); - it('must inline props without children', function() { - const templateBlock = TemplateBlock.create('sayhello', function(block) { + it('must inline props without children', () => { + const templateBlock = TemplateBlock.create('sayhello', (block) => { return { message: block.kwargs.tag + ' ' + block.kwargs.name }; @@ -131,16 +131,16 @@ describe('TemplateBlock', function() { // Render a template using the block const src = '{% sayhello name="Samy", tag="p" %}{% endsayhello %}'; return Promise.nfcall(env.renderString.bind(env), src) - .then(function(res) { + .then((res) => { expect(res).toBe('<xblock name="sayhello" props="{"message":"p Samy"}"></xblock>'); }); }); - it('must accept an async function', function() { - const templateBlock = TemplateBlock.create('sayhello', function(block) { + it('must accept an async function', () => { + const templateBlock = TemplateBlock.create('sayhello', (block) => { return Promise() .delay(1) - .then(function() { + .then(() => { return { children: 'Hello ' + block.children }; @@ -157,19 +157,19 @@ describe('TemplateBlock', function() { // Render a template using the block const src = '{% sayhello %}Samy{% endsayhello %}'; return Promise.nfcall(env.renderString.bind(env), src) - .then(function(res) { + .then((res) => { expect(res).toBe('<xblock name="sayhello" props="{}">Hello Samy</xblock>'); }); }); - it('must handle nested blocks', function() { + it('must handle nested blocks', () => { const templateBlock = new TemplateBlock({ name: 'yoda', blocks: Immutable.List(['start', 'end']), process(block) { const nested = {}; - block.blocks.forEach(function(blk) { + block.blocks.forEach((blk) => { nested[blk.name] = blk.children.trim(); }); @@ -187,12 +187,12 @@ describe('TemplateBlock', function() { // Render a template using the block const src = '{% yoda %}{% start %}this sentence should be{% end %}inverted{% endyoda %}'; return Promise.nfcall(env.renderString.bind(env), src) - .then(function(res) { + .then((res) => { expect(res).toBe('<xblock name="yoda" props="{}"><p class="yoda">inverted this sentence should be</p></xblock>'); }); }); - it('must handle multiple inline blocks', function() { + it('must handle multiple inline blocks', () => { const templateBlock = new TemplateBlock({ name: 'math', process(block) { @@ -210,7 +210,7 @@ describe('TemplateBlock', function() { // Render a template using the block after replacing shortcuts const src = 'There should be two inline blocks as a result: {% math %}a = b{% endmath %} and {% math %}c = d{% endmath %}'; return Promise.nfcall(env.renderString.bind(env), src) - .then(function(res) { + .then((res) => { expect(res).toBe('There should be two inline blocks as a result: <xblock name="math" props="{}"><math>a = b</math></xblock> and <xblock name="math" props="{}"><math>c = d</math></xblock>'); }); }); diff --git a/packages/gitbook/src/models/__tests__/templateEngine.js b/packages/gitbook/src/models/__tests__/templateEngine.js index 30cd543..b4118f3 100644 --- a/packages/gitbook/src/models/__tests__/templateEngine.js +++ b/packages/gitbook/src/models/__tests__/templateEngine.js @@ -1,9 +1,9 @@ -describe('TemplateBlock', function() { +describe('TemplateBlock', () => { const TemplateEngine = require('../templateEngine'); - describe('create', function() { - it('must initialize with a list of filters', function() { + describe('create', () => { + it('must initialize with a list of filters', () => { const engine = TemplateEngine.create({ filters: { hello(name) { @@ -17,7 +17,7 @@ describe('TemplateBlock', function() { expect(res).toBe('Hello Luke!'); }); - it('must initialize with a list of globals', function() { + it('must initialize with a list of globals', () => { const engine = TemplateEngine.create({ globals: { hello(name) { @@ -31,7 +31,7 @@ describe('TemplateBlock', function() { expect(res).toBe('Hello Luke!'); }); - it('must pass context to filters and blocks', function() { + it('must pass context to filters and blocks', () => { const engine = TemplateEngine.create({ filters: { hello(name) { diff --git a/packages/gitbook/src/models/book.js b/packages/gitbook/src/models/book.js index 4668154..ca445ea 100644 --- a/packages/gitbook/src/models/book.js +++ b/packages/gitbook/src/models/book.js @@ -256,7 +256,7 @@ class Book extends Record(DEFAULTS) { ]; // List their extensions - const exts = clues.map(function(clue) { + const exts = clues.map((clue) => { const file = clue.getFile(); if (file.exists()) { return file.getParser().getExtensions().first(); @@ -268,7 +268,7 @@ class Book extends Record(DEFAULTS) { exts.push('.md'); // Choose the first non null - return exts.find(function(e) { return e !== null; }); + return exts.find((e) => { return e !== null; }); } /** diff --git a/packages/gitbook/src/models/config.js b/packages/gitbook/src/models/config.js index 6a0be5e..f9e62c9 100644 --- a/packages/gitbook/src/models/config.js +++ b/packages/gitbook/src/models/config.js @@ -1,181 +1,179 @@ const is = require('is'); -const Immutable = require('immutable'); +const { Record, fromJS } = require('immutable'); const File = require('./file'); const PluginDependency = require('./pluginDependency'); const configDefault = require('../constants/configDefault'); const reducedObject = require('../utils/reducedObject'); -const Config = Immutable.Record({ - file: File(), - values: configDefault -}, 'Config'); - -Config.prototype.getFile = function() { - return this.get('file'); -}; - -Config.prototype.getValues = function() { - return this.get('values'); +const DEFAULTS = { + file: new File(), + values: configDefault }; -/** - * Return minimum version of configuration, - * Basically it returns the current config minus the default one - * @return {Map} - */ -Config.prototype.toReducedVersion = function() { - return reducedObject(configDefault, this.getValues()); -}; +class Config extends Record(DEFAULTS) { + getFile() { + return this.get('file'); + } -/** - * Render config as text - * @return {Promise<String>} - */ -Config.prototype.toText = function() { - return JSON.stringify(this.toReducedVersion().toJS(), null, 4); -}; + getValues() { + return this.get('values'); + } -/** - * Change the file for the configuration - * @param {File} file - * @return {Config} - */ -Config.prototype.setFile = function(file) { - return this.set('file', file); -}; + /** + * Return minimum version of configuration, + * Basically it returns the current config minus the default one + * @return {Map} + */ + toReducedVersion() { + return reducedObject(configDefault, this.getValues()); + } -/** - * Return a configuration value by its key path - * @param {String} key - * @return {Mixed} - */ -Config.prototype.getValue = function(keyPath, def) { - const values = this.getValues(); - keyPath = Config.keyToKeyPath(keyPath); - - if (!values.hasIn(keyPath)) { - return Immutable.fromJS(def); + /** + * Render config as text + * @return {String} + */ + toText() { + return JSON.stringify(this.toReducedVersion().toJS(), null, 4); } - return values.getIn(keyPath); -}; + /** + * Change the file for the configuration + * @param {File} file + * @return {Config} + */ + setFile(file) { + return this.set('file', file); + } -/** - * Update a configuration value - * @param {String} key - * @param {Mixed} value - * @return {Config} - */ -Config.prototype.setValue = function(keyPath, value) { - keyPath = Config.keyToKeyPath(keyPath); + /** + * Return a configuration value by its key path + * @param {String} key + * @return {Mixed} + */ + getValue(keyPath, def) { + const values = this.getValues(); + keyPath = Config.keyToKeyPath(keyPath); - value = Immutable.fromJS(value); + if (!values.hasIn(keyPath)) { + return fromJS(def); + } - let values = this.getValues(); - values = values.setIn(keyPath, value); + return values.getIn(keyPath); + } - return this.set('values', values); -}; + /** + * Update a configuration value + * @param {String} key + * @param {Mixed} value + * @return {Config} + */ + setValue(keyPath, value) { + keyPath = Config.keyToKeyPath(keyPath); -/** - * Return a list of plugin dependencies - * @return {List<PluginDependency>} - */ -Config.prototype.getPluginDependencies = function() { - const plugins = this.getValue('plugins'); - - if (is.string(plugins)) { - return PluginDependency.listFromString(plugins); - } else { - return PluginDependency.listFromArray(plugins); - } -}; + value = fromJS(value); -/** - * Return a plugin dependency by its name - * @param {String} name - * @return {PluginDependency} - */ -Config.prototype.getPluginDependency = function(name) { - const plugins = this.getPluginDependencies(); - - return plugins.find(function(dep) { - return dep.getName() === name; - }); -}; + let values = this.getValues(); + values = values.setIn(keyPath, value); -/** - * Update the list of plugins dependencies - * @param {List<PluginDependency>} - * @return {Config} - */ -Config.prototype.setPluginDependencies = function(deps) { - const plugins = PluginDependency.listToArray(deps); + return this.set('values', values); + } - return this.setValue('plugins', plugins); -}; + /** + * Return a list of plugin dependencies + * @return {List<PluginDependency>} + */ + getPluginDependencies() { + const plugins = this.getValue('plugins'); + + if (is.string(plugins)) { + return PluginDependency.listFromString(plugins); + } else { + return PluginDependency.listFromArray(plugins); + } + } + /** + * Return a plugin dependency by its name + * @param {String} name + * @return {PluginDependency} + */ + getPluginDependency(name) { + const plugins = this.getPluginDependencies(); + return plugins.find((dep) => { + return dep.getName() === name; + }); + } -/** - * Update values for an existing configuration - * @param {Object} values - * @returns {Config} - */ -Config.prototype.updateValues = function(values) { - values = Immutable.fromJS(values); + /** + * Update the list of plugins dependencies + * @param {List<PluginDependency>} + * @return {Config} + */ + setPluginDependencies(deps) { + const plugins = PluginDependency.listToArray(deps); + return this.setValue('plugins', plugins); + } - return this.set('values', values); -}; + /** + * Update values for an existing configuration + * @param {Object} values + * @returns {Config} + */ + updateValues(values) { + values = fromJS(values); + return this.set('values', values); + } -/** - * Update values for an existing configuration - * @param {Config} config - * @param {Object} values - * @returns {Config} - */ -Config.prototype.mergeValues = function(values) { - let currentValues = this.getValues(); - values = Immutable.fromJS(values); + /** + * Update values for an existing configuration + * @param {Config} config + * @param {Object} values + * @returns {Config} + */ + mergeValues(values) { + let currentValues = this.getValues(); + values = fromJS(values); - currentValues = currentValues.mergeDeep(values); + currentValues = currentValues.mergeDeep(values); - return this.set('values', currentValues); -}; + return this.set('values', currentValues); + } -/** - * Create a new config for a file - * @param {File} file - * @param {Object} values - * @returns {Config} - */ -Config.create = function(file, values) { - return new Config({ - file, - values: Immutable.fromJS(values) - }); -}; + /** + * Create a new config for a file + * @param {File} file + * @param {Object} values + * @returns {Config} + */ + static create(file, values) { + return new Config({ + file, + values: fromJS(values) + }); + } -/** - * Create a new config - * @param {Object} values - * @returns {Config} - */ -Config.createWithValues = function(values) { - return new Config({ - values: Immutable.fromJS(values) - }); -}; + /** + * Create a new config + * @param {Object} values + * @returns {Config} + */ + static createWithValues(values) { + return new Config({ + values: fromJS(values) + }); + } -/** - * Convert a keyPath to an array of keys - * @param {String|Array} - * @return {Array} - */ -Config.keyToKeyPath = function(keyPath) { - if (is.string(keyPath)) keyPath = keyPath.split('.'); - return keyPath; -}; + /** + * Convert a keyPath to an array of keys + * @param {String|Array} + * @return {Array} + */ + static keyToKeyPath(keyPath) { + if (is.string(keyPath)) keyPath = keyPath.split('.'); + return keyPath; + } +} module.exports = Config; diff --git a/packages/gitbook/src/models/file.js b/packages/gitbook/src/models/file.js index 84828ce..8654bc1 100644 --- a/packages/gitbook/src/models/file.js +++ b/packages/gitbook/src/models/file.js @@ -1,89 +1,116 @@ const path = require('path'); -const Immutable = require('immutable'); +const { Record } = require('immutable'); +const error = require('../utils/error'); const parsers = require('../parsers'); -const File = Immutable.Record({ +const DEFAULTS = { // Path of the file, relative to the FS - path: String(), - + path: String(), // Time when file data last modified - mtime: Date() -}); - -File.prototype.getPath = function() { - return this.get('path'); + mtime: Date() }; -File.prototype.getMTime = function() { - return this.get('mtime'); -}; +class File extends Record(DEFAULTS) { + getPath() { + return this.get('path'); + } -/** - Does the file exists / is set + getMTime() { + return this.get('mtime'); + } - @return {Boolean} -*/ -File.prototype.exists = function() { - return Boolean(this.getPath()); -}; + /** + * Return the file extension. + * @return {String} + */ + get extension() { + return path.extname(this.getPath()).toLowerCase(); + } -/** - Return type of file ('markdown' or 'asciidoc') - - @return {String} -*/ -File.prototype.getType = function() { - const parser = this.getParser(); - if (parser) { - return parser.getName(); - } else { - return undefined; + /** + * Return the parser for this file.. + * @return {Parser} + */ + get parser() { + return parsers.getByExt(this.extension); } -}; -/** - Return extension of this file (lowercased) + /** + * Return type of file ('markdown' or 'asciidoc'). + * @return {String} + */ + get type() { + const { parser } = this; + return parser ? parser.name : undefined; + } - @return {String} -*/ -File.prototype.getExtension = function() { - return path.extname(this.getPath()).toLowerCase(); -}; + /** + * Does the file exists / is set. + * @return {Boolean} + */ + exists() { + return Boolean(this.getPath()); + } -/** - Return parser for this file + /** + * Read and parse the file. + * @param {FS} fs + * @return {Promise<Document>} document + */ + parse(fs) { + const { parser } = this; + + if (!parser) { + return Promise.reject( + error.FileNotParsableError({ + filename: this.path + }) + ); + } + + return fs.readAsString(this.path) + .then((content) => { + const document = parser.toDocument(content); + return document; + }); + } - @return {Parser} -*/ -File.prototype.getParser = function() { - return parsers.getByExt(this.getExtension()); -}; + getType() { + return this.type; + } -/** - Create a file from stats informations - - @param {String} filepath - @param {Object|fs.Stats} stat - @return {File} -*/ -File.createFromStat = function createFromStat(filepath, stat) { - return new File({ - path: filepath, - mtime: stat.mtime - }); -}; + getExtension() { + return this.extension; + } -/** - Create a file with only a path + getParser() { + return this.parser; + } - @param {String} filepath - @return {File} -*/ -File.createWithFilepath = function createWithFilepath(filepath) { - return new File({ - path: filepath - }); -}; + /** + * Create a file from stats informations. + * @param {String} filepath + * @param {Object|fs.Stats} stat + * @return {File} + */ + static createFromStat(filepath, stat) { + return new File({ + path: filepath, + mtime: stat.mtime + }); + } + + /** + * Create a file with only a path. + * @param {String} filepath + * @return {File} + */ + static createWithFilepath(filepath) { + return new File({ + path: filepath + }); + } +} module.exports = File; diff --git a/packages/gitbook/src/models/fs.js b/packages/gitbook/src/models/fs.js index 7afbfbd..840c50b 100644 --- a/packages/gitbook/src/models/fs.js +++ b/packages/gitbook/src/models/fs.js @@ -70,7 +70,7 @@ FS.prototype.exists = function(filename) { const that = this; return Promise() - .then(function() { + .then(() => { filename = that.resolve(filename); const exists = that.get('fsExists'); @@ -87,7 +87,7 @@ FS.prototype.read = function(filename) { const that = this; return Promise() - .then(function() { + .then(() => { filename = that.resolve(filename); const read = that.get('fsReadFile'); @@ -104,7 +104,7 @@ FS.prototype.readAsString = function(filename, encoding) { encoding = encoding || 'utf8'; return this.read(filename) - .then(function(buf) { + .then((buf) => { return buf.toString(encoding); }); }; @@ -124,7 +124,7 @@ FS.prototype.readAsStream = function(filename) { } return this.read(filename) - .then(function(buf) { + .then((buf) => { const bufferStream = new stream.PassThrough(); bufferStream.end(buf); @@ -141,13 +141,13 @@ FS.prototype.statFile = function(filename) { const that = this; return Promise() - .then(function() { + .then(() => { const filepath = that.resolve(filename); const stat = that.get('fsStatFile'); return stat(filepath); }) - .then(function(stat) { + .then((stat) => { return File.createFromStat(filename, stat); }); }; @@ -163,13 +163,13 @@ FS.prototype.readDir = function(dirname) { const that = this; return Promise() - .then(function() { + .then(() => { const dirpath = that.resolve(dirname); const readDir = that.get('fsReadDir'); return readDir(dirpath); }) - .then(function(files) { + .then((files) => { return Immutable.List(files); }); }; @@ -183,7 +183,7 @@ FS.prototype.readDir = function(dirname) { */ FS.prototype.listFiles = function(dirname) { return this.readDir(dirname) - .then(function(files) { + .then((files) => { return files.filterNot(pathIsFolder); }); }; @@ -200,8 +200,8 @@ FS.prototype.listAllFiles = function(dirName, filterFn) { dirName = dirName || '.'; return this.readDir(dirName) - .then(function(files) { - return Promise.reduce(files, function(out, file) { + .then((files) => { + return Promise.reduce(files, (out, file) => { const isDirectory = pathIsFolder(file); const newDirName = path.join(dirName, file); @@ -214,7 +214,7 @@ FS.prototype.listAllFiles = function(dirName, filterFn) { } return that.listAllFiles(newDirName, filterFn) - .then(function(inner) { + .then((inner) => { return out.concat(inner); }); }, Immutable.List()); @@ -231,8 +231,8 @@ FS.prototype.listAllFiles = function(dirName, filterFn) { */ FS.prototype.findFile = function(dirname, filename) { return this.listFiles(dirname) - .then(function(files) { - return files.find(function(file) { + .then((files) => { + return files.find((file) => { return (file.toLowerCase() == filename.toLowerCase()); }); }); @@ -250,7 +250,7 @@ FS.prototype.loadAsObject = function(filename) { const fsLoadObject = this.get('fsLoadObject'); return this.exists(filename) - .then(function(exists) { + .then((exists) => { if (!exists) { const err = new Error('Module doesn\'t exist'); err.code = 'MODULE_NOT_FOUND'; @@ -262,7 +262,7 @@ FS.prototype.loadAsObject = function(filename) { return fsLoadObject(that.resolve(filename)); } else { return that.readAsString(filename) - .then(function(str) { + .then((str) => { return JSON.parse(str); }); } diff --git a/packages/gitbook/src/models/glossary.js b/packages/gitbook/src/models/glossary.js index e269b14..f958f63 100644 --- a/packages/gitbook/src/models/glossary.js +++ b/packages/gitbook/src/models/glossary.js @@ -1,109 +1,89 @@ -const Immutable = require('immutable'); +const { Record, OrderedMap } = require('immutable'); -const error = require('../utils/error'); const File = require('./file'); const GlossaryEntry = require('./glossaryEntry'); -const parsers = require('../parsers'); -const Glossary = Immutable.Record({ - file: File(), - entries: Immutable.OrderedMap() -}); - -Glossary.prototype.getFile = function() { - return this.get('file'); -}; - -Glossary.prototype.getEntries = function() { - return this.get('entries'); -}; - -/** - Return an entry by its name - - @param {String} name - @return {GlossaryEntry} -*/ -Glossary.prototype.getEntry = function(name) { - const entries = this.getEntries(); - const id = GlossaryEntry.nameToID(name); - - return entries.get(id); +const DEFAULTS = { + file: new File(), + entries: OrderedMap() }; -/** - Render glossary as text - - @return {Promise<String>} -*/ -Glossary.prototype.toText = function(parser) { - const file = this.getFile(); - const entries = this.getEntries(); - - parser = parser ? parsers.getByExt(parser) : file.getParser(); - - if (!parser) { - throw error.FileNotParsableError({ - filename: file.getPath() - }); +class Glossary extends Record(DEFAULTS) { + getFile() { + return this.get('file'); } - return parser.renderGlossary(entries.toJS()); -}; - - -/** - Add/Replace an entry to a glossary - - @param {Glossary} glossary - @param {GlossaryEntry} entry - @return {Glossary} -*/ -Glossary.addEntry = function addEntry(glossary, entry) { - const id = entry.getID(); - let entries = glossary.getEntries(); - - entries = entries.set(id, entry); - return glossary.set('entries', entries); -}; + getEntries() { + return this.get('entries'); + } -/** - Add/Replace an entry to a glossary by name/description + /** + * Set file linked to the glossary. + * @param {File} file + * @return {Readme} + */ + setFile(file) { + return this.merge({ file }); + } - @param {Glossary} glossary - @param {GlossaryEntry} entry - @return {Glossary} -*/ -Glossary.addEntryByName = function addEntryByName(glossary, name, description) { - const entry = new GlossaryEntry({ - name, - description - }); + /** + * Return an entry by its name. + * @param {String} name + * @return {GlossaryEntry} + */ + getEntry(name) { + const { entries } = this; + const id = GlossaryEntry.nameToID(name); - return Glossary.addEntry(glossary, entry); -}; + return entries.get(id); + } -/** - Create a glossary from a list of entries + /** + * Add/Replace an entry to a glossary. + * @param {GlossaryEntry} entry + * @return {Glossary} + */ + addEntry(entry) { + const id = entry.getID(); + let { entries } = this; + + entries = entries.set(id, entry); + return this.set('entries', entries); + } - @param {String} filename - @param {Array|List} entries - @return {Glossary} -*/ -Glossary.createFromEntries = function createFromEntries(file, entries) { - entries = entries.map(function(entry) { - if (!(entry instanceof GlossaryEntry)) { - entry = new GlossaryEntry(entry); - } + /** + * Add/Replace an entry to a glossary by name/description. + * @param {GlossaryEntry} entry + * @return {Glossary} + */ + addEntryByName(name, description) { + const entry = new GlossaryEntry({ + name, + description + }); - return [entry.getID(), entry]; - }); + return this.addEntry(entry); + } - return new Glossary({ - file, - entries: Immutable.OrderedMap(entries) - }); -}; + /** + * Create a glossary from a list of entries. + * + * @param {Array|List} entries + * @return {Glossary} + */ + static createFromEntries(entries) { + entries = entries.map((entry) => { + if (!(entry instanceof GlossaryEntry)) { + entry = new GlossaryEntry(entry); + } + + return [entry.id, entry]; + }); + return new Glossary({ + entries: OrderedMap(entries) + }); + } +} module.exports = Glossary; diff --git a/packages/gitbook/src/models/glossaryEntry.js b/packages/gitbook/src/models/glossaryEntry.js index b36b276..35ea1ca 100644 --- a/packages/gitbook/src/models/glossaryEntry.js +++ b/packages/gitbook/src/models/glossaryEntry.js @@ -1,43 +1,49 @@ -const Immutable = require('immutable'); +const { Record } = require('immutable'); const slug = require('github-slugid'); -/* - A definition represents an entry in the glossary -*/ - -const GlossaryEntry = Immutable.Record({ - name: String(), - description: String() -}); - -GlossaryEntry.prototype.getName = function() { - return this.get('name'); -}; - -GlossaryEntry.prototype.getDescription = function() { - return this.get('description'); +const DEFAULTS = { + name: String(), + description: String() }; - /** - Get identifier for this entry - - @retrun {Boolean} -*/ -GlossaryEntry.prototype.getID = function() { - return GlossaryEntry.nameToID(this.getName()); -}; - - -/** - Normalize a glossary entry name into a unique id - - @param {String} - @return {String} -*/ -GlossaryEntry.nameToID = function nameToID(name) { - return slug(name); -}; - + * A definition represents an entry in the glossary. + * @param {Class} + */ + +class GlossaryEntry extends Record(DEFAULTS) { + + /** + * Get identifier for this entry + * + * @return {String} + */ + get id() { + return GlossaryEntry.nameToID(this.name); + } + + getName() { + return this.get('name'); + } + + getDescription() { + return this.get('description'); + } + + getID() { + return this.id; + } + + + /** + * Normalize a glossary entry name into a unique id + * + * @param {String} + * @return {String} + */ + static nameToID(name) { + return slug(name); + } +} module.exports = GlossaryEntry; diff --git a/packages/gitbook/src/models/language.js b/packages/gitbook/src/models/language.js index 1413091..1ca0a28 100644 --- a/packages/gitbook/src/models/language.js +++ b/packages/gitbook/src/models/language.js @@ -1,21 +1,27 @@ const path = require('path'); -const Immutable = require('immutable'); +const { Record } = require('immutable'); -const Language = Immutable.Record({ - title: String(), - path: String() -}); - -Language.prototype.getTitle = function() { - return this.get('title'); +const DEFAULTS = { + title: String(), + path: String() }; -Language.prototype.getPath = function() { - return this.get('path'); -}; +class Language extends Record(DEFAULTS) { + get id() { + return path.basename(this.path); + } -Language.prototype.getID = function() { - return path.basename(this.getPath()); -}; + getTitle() { + return this.get('title'); + } + + getPath() { + return this.get('path'); + } + + getID() { + return this.id; + } +} module.exports = Language; diff --git a/packages/gitbook/src/models/languages.js b/packages/gitbook/src/models/languages.js index 9540546..ae88b88 100644 --- a/packages/gitbook/src/models/languages.js +++ b/packages/gitbook/src/models/languages.js @@ -1,71 +1,77 @@ -const Immutable = require('immutable'); +const { OrderedMap, Record } = require('immutable'); const File = require('./file'); const Language = require('./language'); -const Languages = Immutable.Record({ - file: File(), - list: Immutable.OrderedMap() -}); - -Languages.prototype.getFile = function() { - return this.get('file'); +const DEFAULTS = { + file: new File(), + list: OrderedMap() }; -Languages.prototype.getList = function() { - return this.get('list'); -}; +class Languages extends Record(DEFAULTS) { + getFile() { + return this.get('file'); + } -/** - Get default languages + getList() { + return this.get('list'); + } - @return {Language} -*/ -Languages.prototype.getDefaultLanguage = function() { - return this.getList().first(); -}; + /** + * Set file linked to the languages index. + * @param {File} file + * @return {Languages} + */ + setFile(file) { + return this.merge({ file }); + } -/** - Get a language by its ID + /** + * Get default languages + * @return {Language} + */ + getDefaultLanguage() { + return this.list.first(); + } - @param {String} lang - @return {Language} -*/ -Languages.prototype.getLanguage = function(lang) { - return this.getList().get(lang); -}; + /** + * Get a language by its ID. + * @param {String} lang + * @return {Language} + */ + getLanguage(lang) { + return this.list.get(lang); + } -/** - Return count of langs + /** + * Return count of langs. + * @return {Number} + */ + getCount() { + return this.list.size; + } - @return {Number} -*/ -Languages.prototype.getCount = function() { - return this.getList().size; -}; + /** + * Create a languages list from a JS object + * + * @param {Array} + * @return {Language} + */ + static createFromList(langs) { + let list = OrderedMap(); -/** - Create a languages list from a JS object - - @param {File} - @param {Array} - @return {Language} -*/ -Languages.createFromList = function(file, langs) { - let list = Immutable.OrderedMap(); - - langs.forEach(function(lang) { - lang = Language({ - title: lang.title, - path: lang.ref + langs.forEach((lang) => { + lang = new Language({ + title: lang.title, + path: lang.path || lang.ref + }); + list = list.set(lang.getID(), lang); }); - list = list.set(lang.getID(), lang); - }); - return Languages({ - file, - list - }); -}; + return new Languages({ + list + }); + } +} module.exports = Languages; diff --git a/packages/gitbook/src/models/page.js b/packages/gitbook/src/models/page.js index e2ab977..577475e 100644 --- a/packages/gitbook/src/models/page.js +++ b/packages/gitbook/src/models/page.js @@ -4,7 +4,7 @@ const yaml = require('js-yaml'); const File = require('./file'); const DEFAULTS = { - file: File(), + file: new File(), // Attributes extracted from the YAML header attributes: Map(), // Content of the page diff --git a/packages/gitbook/src/models/parser.js b/packages/gitbook/src/models/parser.js deleted file mode 100644 index 3769dd3..0000000 --- a/packages/gitbook/src/models/parser.js +++ /dev/null @@ -1,122 +0,0 @@ -const Immutable = require('immutable'); -const Promise = require('../utils/promise'); - -const Parser = Immutable.Record({ - name: String(), - - // List of extensions that can be processed using this parser - extensions: Immutable.List(), - - // Parsing functions - readme: Function(), - langs: Function(), - summary: Function(), - glossary: Function(), - page: Function(), - inline: Function() -}); - -Parser.prototype.getName = function() { - return this.get('name'); -}; - -Parser.prototype.getExtensions = function() { - return this.get('extensions'); -}; - -// PARSE - -Parser.prototype.parseReadme = function(content) { - const readme = this.get('readme'); - return Promise(readme(content)); -}; - -Parser.prototype.parseSummary = function(content) { - const summary = this.get('summary'); - return Promise(summary(content)); -}; - -Parser.prototype.parseGlossary = function(content) { - const glossary = this.get('glossary'); - return Promise(glossary(content)); -}; - -Parser.prototype.preparePage = function(content) { - const page = this.get('page'); - if (!page.prepare) { - return Promise(content); - } - - return Promise(page.prepare(content)); -}; - -Parser.prototype.parsePage = function(content) { - const page = this.get('page'); - return Promise(page(content)); -}; - -Parser.prototype.parseInline = function(content) { - const inline = this.get('inline'); - return Promise(inline(content)); -}; - -Parser.prototype.parseLanguages = function(content) { - const langs = this.get('langs'); - return Promise(langs(content)); -}; - -Parser.prototype.parseInline = function(content) { - const inline = this.get('inline'); - return Promise(inline(content)); -}; - -// TO TEXT - -Parser.prototype.renderLanguages = function(content) { - const langs = this.get('langs'); - return Promise(langs.toText(content)); -}; - -Parser.prototype.renderSummary = function(content) { - const summary = this.get('summary'); - return Promise(summary.toText(content)); -}; - -Parser.prototype.renderGlossary = function(content) { - const glossary = this.get('glossary'); - return Promise(glossary.toText(content)); -}; - -/** - Test if this parser matches an extension - - @param {String} ext - @return {Boolean} -*/ -Parser.prototype.matchExtension = function(ext) { - const exts = this.getExtensions(); - return exts.includes(ext.toLowerCase()); -}; - -/** - Create a new parser using a module (gitbook-markdown, etc) - - @param {String} name - @param {Array<String>} extensions - @param {Object} module - @return {Parser} -*/ -Parser.create = function(name, extensions, module) { - return new Parser({ - name, - extensions: Immutable.List(extensions), - readme: module.readme, - langs: module.langs, - summary: module.summary, - glossary: module.glossary, - page: module.page, - inline: module.inline - }); -}; - -module.exports = Parser; diff --git a/packages/gitbook/src/models/plugin.js b/packages/gitbook/src/models/plugin.js index f2491f2..ed8c20c 100644 --- a/packages/gitbook/src/models/plugin.js +++ b/packages/gitbook/src/models/plugin.js @@ -101,7 +101,7 @@ class Plugin extends Record(DEFAULTS) { blocks = blocks || Map(); return blocks - .map(function(block, blockName) { + .map((block, blockName) => { return TemplateBlock.create(blockName, block); }); } diff --git a/packages/gitbook/src/models/pluginDependency.js b/packages/gitbook/src/models/pluginDependency.js index 4e5d464..5b1f2c8 100644 --- a/packages/gitbook/src/models/pluginDependency.js +++ b/packages/gitbook/src/models/pluginDependency.js @@ -117,7 +117,7 @@ PluginDependency.listFromString = function(s) { */ PluginDependency.listFromArray = function(arr) { return Immutable.List(arr) - .map(function(entry) { + .map((entry) => { if (is.string(entry)) { return PluginDependency.createFromString(entry); } else { @@ -127,7 +127,7 @@ PluginDependency.listFromArray = function(arr) { }); } }) - .filter(function(dep) { + .filter((dep) => { return Boolean(dep.getName()); }); }; @@ -139,7 +139,7 @@ PluginDependency.listFromArray = function(arr) { */ PluginDependency.listToArray = function(list) { return list - .map(function(dep) { + .map((dep) => { let result = ''; if (!dep.isEnabled()) { diff --git a/packages/gitbook/src/models/readme.js b/packages/gitbook/src/models/readme.js index 0fb52b4..59eea22 100644 --- a/packages/gitbook/src/models/readme.js +++ b/packages/gitbook/src/models/readme.js @@ -1,40 +1,49 @@ -const Immutable = require('immutable'); - +const { Record } = require('immutable'); const File = require('./file'); -const Readme = Immutable.Record({ - file: File(), - title: String(), - description: String() -}); - -Readme.prototype.getFile = function() { - return this.get('file'); -}; - -Readme.prototype.getTitle = function() { - return this.get('title'); +const DEFAULTS = { + file: new File(), + title: String(), + description: String() }; -Readme.prototype.getDescription = function() { - return this.get('description'); -}; - -/** - Create a new readme - - @param {File} file - @param {Object} def - @return {Readme} -*/ -Readme.create = function(file, def) { - def = def || {}; - - return new Readme({ - file, - title: def.title || '', - description: def.description || '' - }); -}; +class Readme extends Record(DEFAULTS) { + getFile() { + return this.get('file'); + } + + getTitle() { + return this.get('title'); + } + + getDescription() { + return this.get('description'); + } + + /** + * Set file linked to the readme. + * @param {File} file + * @return {Readme} + */ + setFile(file) { + return this.merge({ file }); + } + + /** + * Create a new readme + * + * @param {File} file + * @param {Object} def + * @return {Readme} + */ + static create(def) { + def = def || {}; + + return new Readme({ + title: def.title || '', + description: def.description || '' + }); + } +} module.exports = Readme; diff --git a/packages/gitbook/src/models/summary.js b/packages/gitbook/src/models/summary.js index edc202e..f77b732 100644 --- a/packages/gitbook/src/models/summary.js +++ b/packages/gitbook/src/models/summary.js @@ -1,225 +1,208 @@ const is = require('is'); -const Immutable = require('immutable'); +const { List, Record } = require('immutable'); const error = require('../utils/error'); const LocationUtils = require('../utils/location'); const File = require('./file'); const SummaryPart = require('./summaryPart'); const SummaryArticle = require('./summaryArticle'); -const parsers = require('../parsers'); -const Summary = Immutable.Record({ - file: File(), - parts: Immutable.List() -}, 'Summary'); - -Summary.prototype.getFile = function() { - return this.get('file'); -}; - -Summary.prototype.getParts = function() { - return this.get('parts'); -}; - -/** - Return a part by its index - - @param {Number} - @return {Part} -*/ -Summary.prototype.getPart = function(i) { - const parts = this.getParts(); - return parts.get(i); +const DEFAULTS = { + file: new File(), + parts: List() }; -/** - Return an article using an iterator to find it. - if "partIter" is set, it can also return a Part. - - @param {Function} iter - @param {Function} partIter - @return {Article|Part} -*/ -Summary.prototype.getArticle = function(iter, partIter) { - const parts = this.getParts(); - - return parts.reduce(function(result, part) { - if (result) return result; - - if (partIter && partIter(part)) return part; - return SummaryArticle.findArticle(part, iter); - }, null); -}; +class Summary extends Record(DEFAULTS) { + getFile() { + return this.get('file'); + } + getParts() { + return this.get('parts'); + } -/** - Return a part/article by its level - - @param {String} level - @return {Article|Part} -*/ -Summary.prototype.getByLevel = function(level) { - function iterByLevel(article) { - return (article.getLevel() === level); + /** + * Set file linked to the summary. + * @param {File} file + * @return {Summary} + */ + setFile(file) { + return this.merge({ file }); } - return this.getArticle(iterByLevel, iterByLevel); -}; + /** + * Return a part by its index. + * @param {Number} + * @return {Part} + */ + getPart(i) { + const parts = this.getParts(); + return parts.get(i); + } -/** - Return an article by its path - - @param {String} filePath - @return {Article} -*/ -Summary.prototype.getByPath = function(filePath) { - return this.getArticle(function(article) { - const articlePath = article.getPath(); - - return ( - articlePath && - LocationUtils.areIdenticalPaths(articlePath, filePath) - ); - }); -}; + /** + * Return an article using an iterator to find it. + * if "partIter" is set, it can also return a Part. + * + * @param {Function} iter + * @param {Function} partIter + * @return {Article|Part} + */ + getArticle(iter, partIter) { + const parts = this.getParts(); + + return parts.reduce((result, part) => { + if (result) return result; + + if (partIter && partIter(part)) return part; + return SummaryArticle.findArticle(part, iter); + }, null); + } -/** - Return the first article - - @return {Article} -*/ -Summary.prototype.getFirstArticle = function() { - return this.getArticle(function(article) { - return true; - }); -}; + /** + * Return a part/article by its level. + * + * @param {String} level + * @return {Article|Part} + */ + getByLevel(level) { + function iterByLevel(article) { + return (article.getLevel() === level); + } -/** - Return next article of an article + return this.getArticle(iterByLevel, iterByLevel); + } - @param {Article} current - @return {Article} -*/ -Summary.prototype.getNextArticle = function(current) { - const level = is.string(current) ? current : current.getLevel(); - let wasPrev = false; + /** + * Return an article by its path. + * + * @param {String} filePath + * @return {Article} + */ + getByPath(filePath) { + return this.getArticle((article) => { + const articlePath = article.getPath(); + + return ( + articlePath && + LocationUtils.areIdenticalPaths(articlePath, filePath) + ); + }); + } - return this.getArticle(function(article) { - if (wasPrev) return true; + /** + * Return the first article. + * @return {Article} + */ + getFirstArticle() { + return this.getArticle((article) => { + return true; + }); + } - wasPrev = article.getLevel() == level; - return false; - }); -}; + /** + * Return next article of an article. + * + * @param {Article} current + * @return {Article} + */ + getNextArticle(current) { + const level = is.string(current) ? current : current.getLevel(); + let wasPrev = false; + + return this.getArticle((article) => { + if (wasPrev) return true; + + wasPrev = article.getLevel() == level; + return false; + }); + } -/** - Return previous article of an article + /** + * Return previous article of an article. + * + * @param {Article} current + * @return {Article} + */ + getPrevArticle(current) { + const level = is.string(current) ? current : current.getLevel(); + let prev = undefined; + + this.getArticle((article) => { + if (article.getLevel() == level) { + return true; + } + + prev = article; + return false; + }); - @param {Article} current - @return {Article} -*/ -Summary.prototype.getPrevArticle = function(current) { - const level = is.string(current) ? current : current.getLevel(); - let prev = undefined; + return prev; + } - this.getArticle(function(article) { - if (article.getLevel() == level) { - return true; + /** + * Return the parent article, or parent part of an article. + * + * @param {String|Article} current + * @return {Article|Part|Null} + */ + getParent(level) { + // Coerce to level + level = is.string(level) ? level : level.getLevel(); + + // Get parent level + const parentLevel = getParentLevel(level); + if (!parentLevel) { + return null; } - prev = article; - return false; - }); - - return prev; -}; - -/** - Return the parent article, or parent part of an article - - @param {String|Article} current - @return {Article|Part|Null} -*/ -Summary.prototype.getParent = function(level) { - // Coerce to level - level = is.string(level) ? level : level.getLevel(); - - // Get parent level - const parentLevel = getParentLevel(level); - if (!parentLevel) { - return null; + // Get parent of the position + const parentArticle = this.getByLevel(parentLevel); + return parentArticle || null; } - // Get parent of the position - const parentArticle = this.getByLevel(parentLevel); - return parentArticle || null; -}; + /** + * Return all articles as a list. + * + * @return {List<Article>} + */ + getArticlesAsList() { + const accu = []; -/** - Render summary as text + this.getArticle((article) => { + accu.push(article); + }); - @param {String} parseExt Extension of the parser to use - @return {Promise<String>} -*/ -Summary.prototype.toText = function(parseExt) { - const file = this.getFile(); - const parts = this.getParts(); + return List(accu); + } - const parser = parseExt ? parsers.getByExt(parseExt) : file.getParser(); + /** + * Create a new summary for a list of parts. + * + * @param {List|Array} parts + * @return {Summary} + */ + static createFromParts(parts) { + parts = parts.map((part, i) => { + if (part instanceof SummaryPart) { + return part; + } + + return SummaryPart.create(part, i + 1); + }); - if (!parser) { - throw error.FileNotParsableError({ - filename: file.getPath() + return new Summary({ + parts: new List(parts) }); } - - return parser.renderSummary({ - parts: parts.toJS() - }); -}; - -/** - Return all articles as a list - - @return {List<Article>} -*/ -Summary.prototype.getArticlesAsList = function() { - const accu = []; - - this.getArticle(function(article) { - accu.push(article); - }); - - return Immutable.List(accu); -}; - -/** - Create a new summary for a list of parts - - @param {Lust|Array} parts - @return {Summary} -*/ -Summary.createFromParts = function createFromParts(file, parts) { - parts = parts.map(function(part, i) { - if (part instanceof SummaryPart) { - return part; - } - - return SummaryPart.create(part, i + 1); - }); - - return new Summary({ - file, - parts: new Immutable.List(parts) - }); -}; +} /** - Returns parent level of a level - - @param {String} level - @return {String} -*/ + * Returns parent level of a level. + * + * @param {String} level + * @return {String} + */ function getParentLevel(level) { const parts = level.split('.'); return parts.slice(0, -1).join('.'); diff --git a/packages/gitbook/src/models/summaryArticle.js b/packages/gitbook/src/models/summaryArticle.js index 919e6b9..dcbfddb 100644 --- a/packages/gitbook/src/models/summaryArticle.js +++ b/packages/gitbook/src/models/summaryArticle.js @@ -1,189 +1,186 @@ -const Immutable = require('immutable'); +const { Record, List } = require('immutable'); const location = require('../utils/location'); -/* - An article represents an entry in the Summary / table of Contents -*/ - -const SummaryArticle = Immutable.Record({ +const DEFAULTS = { level: String(), title: String(), ref: String(), - articles: Immutable.List() -}, 'SummaryArticle'); - -SummaryArticle.prototype.getLevel = function() { - return this.get('level'); -}; - -SummaryArticle.prototype.getTitle = function() { - return this.get('title'); -}; - -SummaryArticle.prototype.getRef = function() { - return this.get('ref'); -}; - -SummaryArticle.prototype.getArticles = function() { - return this.get('articles'); + articles: List() }; /** - * Return how deep the article is. - * The README has a depth of 1 - * - * @return {Number} + * An article represents an entry in the Summary / table of Contents. + * @type {Class} */ -SummaryArticle.prototype.getDepth = function() { - return (this.getLevel().split('.').length - 1); -}; - -/** - * Get path (without anchor) to the pointing file. - * It also normalizes the file path. - * - * @return {String} - */ -SummaryArticle.prototype.getPath = function() { - if (this.isExternal()) { - return undefined; +class SummaryArticle extends Record(DEFAULTS) { + getLevel() { + return this.get('level'); } - const ref = this.getRef(); - if (!ref) { - return undefined; + getTitle() { + return this.get('title'); } - const parts = ref.split('#'); + getRef() { + return this.get('ref'); + } - const pathname = (parts.length > 1 ? parts.slice(0, -1).join('#') : ref); + getArticles() { + return this.get('articles'); + } - // Normalize path to remove ('./', '/...', etc) - return location.flatten(pathname); -}; + /** + * Return how deep the article is. + * The README has a depth of 1 + * + * @return {Number} + */ + getDepth() { + return (this.getLevel().split('.').length - 1); + } -/** - * Return url if article is external - * - * @return {String} - */ -SummaryArticle.prototype.getUrl = function() { - return this.isExternal() ? this.getRef() : undefined; -}; + /** + * Get path (without anchor) to the pointing file. + * It also normalizes the file path. + * + * @return {String} + */ + getPath() { + if (this.isExternal()) { + return undefined; + } -/** - * Get anchor for this article (or undefined) - * - * @return {String} - */ -SummaryArticle.prototype.getAnchor = function() { - const ref = this.getRef(); - const parts = ref.split('#'); + const ref = this.getRef(); + if (!ref) { + return undefined; + } - const anchor = (parts.length > 1 ? '#' + parts[parts.length - 1] : undefined); - return anchor; -}; + const parts = ref.split('#'); -/** - * Create a new level for a new child article - * - * @return {String} - */ -SummaryArticle.prototype.createChildLevel = function() { - const level = this.getLevel(); - const subArticles = this.getArticles(); - const childLevel = level + '.' + (subArticles.size + 1); + const pathname = (parts.length > 1 ? parts.slice(0, -1).join('#') : ref); - return childLevel; -}; + // Normalize path to remove ('./', '/...', etc) + return location.flatten(pathname); + } -/** - * Is article pointing to a page of an absolute url - * - * @return {Boolean} - */ -SummaryArticle.prototype.isPage = function() { - return !this.isExternal() && this.getRef(); -}; + /** + * Return url if article is external. + * @return {String} + */ + getUrl() { + return this.isExternal() ? this.getRef() : undefined; + } -/** - * Check if this article is a file (exatcly) - * - * @param {File} file - * @return {Boolean} - */ -SummaryArticle.prototype.isFile = function(file) { - return ( - file.getPath() === this.getPath() - && this.getAnchor() === undefined - ); -}; + /** + * Get anchor for this article (or undefined). + * @return {String} + */ + getAnchor() { + const ref = this.getRef(); + const parts = ref.split('#'); -/** - * Check if this article is the introduction of the book - * - * @param {Book|Readme} book - * @return {Boolean} - */ -SummaryArticle.prototype.isReadme = function(book) { - const readme = book.getFile ? book : book.getReadme(); - const file = readme.getFile(); + const anchor = (parts.length > 1 ? '#' + parts[parts.length - 1] : undefined); + return anchor; + } - return this.isFile(file); -}; + /** + * Create a new level for a new child article. + * @return {String} + */ + createChildLevel() { + const level = this.getLevel(); + const subArticles = this.getArticles(); + const childLevel = level + '.' + (subArticles.size + 1); -/** - * Is article pointing to aan absolute url - * - * @return {Boolean} - */ -SummaryArticle.prototype.isExternal = function() { - return location.isExternal(this.getRef()); -}; + return childLevel; + } -/** - * Create a SummaryArticle - * - * @param {Object} def - * @return {SummaryArticle} - */ -SummaryArticle.create = function(def, level) { - const articles = (def.articles || []).map(function(article, i) { - if (article instanceof SummaryArticle) { - return article; - } - return SummaryArticle.create(article, [level, i + 1].join('.')); - }); - - return new SummaryArticle({ - level, - title: def.title, - ref: def.ref || def.path || '', - articles: Immutable.List(articles) - }); -}; + /** + * Is article pointing to a page of an absolute url. + * @return {Boolean} + */ + isPage() { + return !this.isExternal() && this.getRef(); + } -/** - * Find an article from a base one - * - * @param {Article|Part} base - * @param {Function(article)} iter - * @return {Article} - */ -SummaryArticle.findArticle = function(base, iter) { - const articles = base.getArticles(); + /** + * Check if this article is a file (exatcly) + * + * @param {File} file + * @return {Boolean} + */ + isFile(file) { + return ( + file.path === this.getPath() + && this.getAnchor() === undefined + ); + } - return articles.reduce(function(result, article) { - if (result) return result; + /** + * Check if this article is the introduction of the book + * + * @param {Book|Readme} book + * @return {Boolean} + */ + isReadme(book) { + const readme = book.getFile ? book : book.getReadme(); + const file = readme.getFile(); + + return this.isFile(file); + } - if (iter(article)) { - return article; - } + /** + * Is article pointing to aan absolute url + * + * @return {Boolean} + */ + isExternal() { + return location.isExternal(this.getRef()); + } - return SummaryArticle.findArticle(article, iter); - }, null); -}; + /** + * Create a SummaryArticle + * + * @param {Object} def + * @return {SummaryArticle} + */ + static create(def, level) { + const articles = (def.articles || []).map((article, i) => { + if (article instanceof SummaryArticle) { + return article; + } + return SummaryArticle.create(article, [level, i + 1].join('.')); + }); + + return new SummaryArticle({ + level, + title: def.title, + ref: def.ref || def.path || '', + articles: List(articles) + }); + } + /** + * Find an article from a base one + * + * @param {Article|Part} base + * @param {Function(article)} iter + * @return {Article} + */ + static findArticle(base, iter) { + const articles = base.getArticles(); + + return articles.reduce((result, article) => { + if (result) return result; + + if (iter(article)) { + return article; + } + + return SummaryArticle.findArticle(article, iter); + }, null); + } +} module.exports = SummaryArticle; diff --git a/packages/gitbook/src/models/summaryPart.js b/packages/gitbook/src/models/summaryPart.js index 0bb5369..d1dc277 100644 --- a/packages/gitbook/src/models/summaryPart.js +++ b/packages/gitbook/src/models/summaryPart.js @@ -1,61 +1,60 @@ -const Immutable = require('immutable'); - +const { Record, List } = require('immutable'); const SummaryArticle = require('./summaryArticle'); -/* - A part represents a section in the Summary / table of Contents -*/ - -const SummaryPart = Immutable.Record({ - level: String(), - title: String(), - articles: Immutable.List() -}); - -SummaryPart.prototype.getLevel = function() { - return this.get('level'); -}; - -SummaryPart.prototype.getTitle = function() { - return this.get('title'); -}; - -SummaryPart.prototype.getArticles = function() { - return this.get('articles'); +const DEFAULTS = { + level: String(), + title: String(), + articles: List() }; /** - * Create a new level for a new child article - * - * @return {String} + * A part represents a section in the Summary / table of Contents. + * @type {Class} */ -SummaryPart.prototype.createChildLevel = function() { - const level = this.getLevel(); - const subArticles = this.getArticles(); - const childLevel = level + '.' + (subArticles.size + 1); - - return childLevel; -}; -/** - * Create a SummaryPart - * - * @param {Object} def - * @return {SummaryPart} - */ -SummaryPart.create = function(def, level) { - const articles = (def.articles || []).map(function(article, i) { - if (article instanceof SummaryArticle) { - return article; - } - return SummaryArticle.create(article, [level, i + 1].join('.')); - }); - - return new SummaryPart({ - level: String(level), - title: def.title, - articles: Immutable.List(articles) - }); -}; +class SummaryPart extends Record(DEFAULTS) { + getLevel() { + return this.get('level'); + } + + getTitle() { + return this.get('title'); + } + + getArticles() { + return this.get('articles'); + } + + /** + * Create a new level for a new child article + * + * @return {String} + */ + createChildLevel() { + const { level, articles } = this; + return `${level}.${articles.size + 1}`; + } + + /** + * Create a SummaryPart + * + * @param {Object} def + * @return {SummaryPart} + */ + static create(def, level) { + const articles = (def.articles || []).map((article, i) => { + if (article instanceof SummaryArticle) { + return article; + } + return SummaryArticle.create(article, [level, i + 1].join('.')); + }); + + return new SummaryPart({ + level: String(level), + title: def.title, + articles: List(articles) + }); + } +} module.exports = SummaryPart; diff --git a/packages/gitbook/src/models/templateBlock.js b/packages/gitbook/src/models/templateBlock.js index 61c006f..55af072 100644 --- a/packages/gitbook/src/models/templateBlock.js +++ b/packages/gitbook/src/models/templateBlock.js @@ -100,7 +100,7 @@ class TemplateBlock extends Record(DEFAULTS) { bodies.push(currentBody); // Append arguments of this block as arguments of the run function - lastBlockArgs.children.forEach(function(child) { + lastBlockArgs.children.forEach((child) => { args.addChild(child); }); @@ -162,14 +162,14 @@ class TemplateBlock extends Record(DEFAULTS) { mainBlock.blocks = blocks; Promise() - .then(function() { + .then(() => { const ctx = extend({ ctx: context }, mainContext); return that.toProps(mainBlock, ctx); }) - .then(function(props) { + .then((props) => { return that.toHTML(props); }) .nodeify(callback); @@ -196,7 +196,7 @@ class TemplateBlock extends Record(DEFAULTS) { return Promise() .then(() => processFn.call(context, inner)) - .then(props => { + .then((props) => { if (is.string(props)) { return { children: props }; } diff --git a/packages/gitbook/src/models/templateEngine.js b/packages/gitbook/src/models/templateEngine.js index 0d0dcb6..8976419 100644 --- a/packages/gitbook/src/models/templateEngine.js +++ b/packages/gitbook/src/models/templateEngine.js @@ -52,7 +52,7 @@ class TemplateEngine extends Record(DEFAULTS) { */ getBlock(name) { const blocks = this.getBlocks(); - return blocks.find(function(block) { + return blocks.find((block) => { return block.getName() === name; }); } @@ -88,12 +88,12 @@ class TemplateEngine extends Record(DEFAULTS) { ); // Add filters - filters.forEach(function(filterFn, filterName) { + filters.forEach((filterFn, filterName) => { env.addFilter(filterName, filterFn.bind(context)); }); // Add blocks - blocks.forEach(function(block) { + blocks.forEach((block) => { const extName = block.getExtensionName(); const Ext = block.toNunjucksExt(context); @@ -101,12 +101,12 @@ class TemplateEngine extends Record(DEFAULTS) { }); // Add globals - globals.forEach(function(globalValue, globalName) { + globals.forEach((globalValue, globalName) => { env.addGlobal(globalName, globalValue); }); // Add other extensions - extensions.forEach(function(ext, extName) { + extensions.forEach((ext, extName) => { env.addExtension(extName, ext); }); diff --git a/packages/gitbook/src/models/templateShortcut.js b/packages/gitbook/src/models/templateShortcut.js index b6e1ed9..4853e1a 100644 --- a/packages/gitbook/src/models/templateShortcut.js +++ b/packages/gitbook/src/models/templateShortcut.js @@ -44,7 +44,7 @@ TemplateShortcut.prototype.getParsers = function() { */ TemplateShortcut.prototype.acceptParser = function(parser) { if (!is.string(parser)) { - parser = parser.getName(); + parser = parser.name; } const parserNames = this.get('parsers'); diff --git a/packages/gitbook/src/modifiers/config/__tests__/addPlugin.js b/packages/gitbook/src/modifiers/config/__tests__/addPlugin.js index 65fd8f9..d3c17d7 100644 --- a/packages/gitbook/src/modifiers/config/__tests__/addPlugin.js +++ b/packages/gitbook/src/modifiers/config/__tests__/addPlugin.js @@ -1,12 +1,12 @@ const addPlugin = require('../addPlugin'); const Config = require('../../../models/config'); -describe('addPlugin', function() { +describe('addPlugin', () => { const config = Config.createWithValues({ plugins: ['hello', 'world', '-disabled'] }); - it('should have correct state of dependencies', function() { + it('should have correct state of dependencies', () => { const disabledDep = config.getPluginDependency('disabled'); expect(disabledDep).toBeDefined(); @@ -14,7 +14,7 @@ describe('addPlugin', function() { expect(disabledDep.isEnabled()).toBeFalsy(); }); - it('should add the plugin to the list', function() { + it('should add the plugin to the list', () => { const newConfig = addPlugin(config, 'test'); const testDep = newConfig.getPluginDependency('test'); diff --git a/packages/gitbook/src/modifiers/config/__tests__/removePlugin.js b/packages/gitbook/src/modifiers/config/__tests__/removePlugin.js index 5450b30..4ec2bf5 100644 --- a/packages/gitbook/src/modifiers/config/__tests__/removePlugin.js +++ b/packages/gitbook/src/modifiers/config/__tests__/removePlugin.js @@ -1,26 +1,26 @@ const removePlugin = require('../removePlugin'); const Config = require('../../../models/config'); -describe('removePlugin', function() { +describe('removePlugin', () => { const config = Config.createWithValues({ plugins: ['hello', 'world', '-disabled'] }); - it('should remove the plugin from the list', function() { + it('should remove the plugin from the list', () => { const newConfig = removePlugin(config, 'hello'); const testDep = newConfig.getPluginDependency('hello'); expect(testDep).toNotBeDefined(); }); - it('should remove the disabled plugin from the list', function() { + it('should remove the disabled plugin from the list', () => { const newConfig = removePlugin(config, 'disabled'); const testDep = newConfig.getPluginDependency('disabled'); expect(testDep).toNotBeDefined(); }); - it('should disable default plugin', function() { + it('should disable default plugin', () => { const newConfig = removePlugin(config, 'search'); const disabledDep = newConfig.getPluginDependency('search'); diff --git a/packages/gitbook/src/modifiers/config/__tests__/togglePlugin.js b/packages/gitbook/src/modifiers/config/__tests__/togglePlugin.js index 6d23ae0..18971b8 100644 --- a/packages/gitbook/src/modifiers/config/__tests__/togglePlugin.js +++ b/packages/gitbook/src/modifiers/config/__tests__/togglePlugin.js @@ -1,12 +1,12 @@ const togglePlugin = require('../togglePlugin'); const Config = require('../../../models/config'); -describe('togglePlugin', function() { +describe('togglePlugin', () => { const config = Config.createWithValues({ plugins: ['hello', 'world', '-disabled'] }); - it('should enable plugin', function() { + it('should enable plugin', () => { const newConfig = togglePlugin(config, 'disabled'); const testDep = newConfig.getPluginDependency('disabled'); @@ -15,7 +15,7 @@ describe('togglePlugin', function() { expect(testDep.isEnabled()).toBeTruthy(); }); - it('should disable plugin', function() { + it('should disable plugin', () => { const newConfig = togglePlugin(config, 'world'); const testDep = newConfig.getPluginDependency('world'); diff --git a/packages/gitbook/src/modifiers/config/hasPlugin.js b/packages/gitbook/src/modifiers/config/hasPlugin.js index 9aab4f2..d156782 100644 --- a/packages/gitbook/src/modifiers/config/hasPlugin.js +++ b/packages/gitbook/src/modifiers/config/hasPlugin.js @@ -7,7 +7,7 @@ * @return {Boolean} */ function hasPlugin(deps, pluginName, version) { - return !!deps.find(function(dep) { + return !!deps.find((dep) => { return dep.getName() === pluginName && (!version || dep.getVersion() === version); }); } diff --git a/packages/gitbook/src/modifiers/config/removePlugin.js b/packages/gitbook/src/modifiers/config/removePlugin.js index c80ab84..9854300 100644 --- a/packages/gitbook/src/modifiers/config/removePlugin.js +++ b/packages/gitbook/src/modifiers/config/removePlugin.js @@ -16,7 +16,7 @@ function removePlugin(config, pluginName) { } // Remove the dependency from the list - deps = deps.filterNot(function(dep) { + deps = deps.filterNot((dep) => { return dep.getName() === pluginName; }); return config.setPluginDependencies(deps); diff --git a/packages/gitbook/src/modifiers/config/togglePlugin.js b/packages/gitbook/src/modifiers/config/togglePlugin.js index 12a6dec..379b942 100644 --- a/packages/gitbook/src/modifiers/config/togglePlugin.js +++ b/packages/gitbook/src/modifiers/config/togglePlugin.js @@ -17,7 +17,7 @@ function togglePlugin(config, pluginName, state) { deps = deps.push(PluginDependency.create(pluginName)); } - deps = deps.map(function(dep) { + deps = deps.map((dep) => { if (dep.getName() === pluginName) { return dep.toggle(state); } diff --git a/packages/gitbook/src/modifiers/index.js b/packages/gitbook/src/modifiers/index.js index ad24604..17bae18 100644 --- a/packages/gitbook/src/modifiers/index.js +++ b/packages/gitbook/src/modifiers/index.js @@ -1,5 +1,5 @@ module.exports = { - Summary: require('./summary'), - Config: require('./config') + Summary: require('./summary'), + Config: require('./config') }; diff --git a/packages/gitbook/src/modifiers/summary/__tests__/editPartTitle.js b/packages/gitbook/src/modifiers/summary/__tests__/editPartTitle.js index aa14a34..20614ab 100644 --- a/packages/gitbook/src/modifiers/summary/__tests__/editPartTitle.js +++ b/packages/gitbook/src/modifiers/summary/__tests__/editPartTitle.js @@ -1,9 +1,8 @@ const Summary = require('../../../models/summary'); -const File = require('../../../models/file'); -describe('editPartTitle', function() { +describe('editPartTitle', () => { const editPartTitle = require('../editPartTitle'); - const summary = Summary.createFromParts(File(), [ + const summary = Summary.createFromParts([ { articles: [ { @@ -21,23 +20,22 @@ describe('editPartTitle', function() { } ]); - it('should correctly set title of first part', function() { + it('should correctly set title of first part', () => { const newSummary = editPartTitle(summary, 0, 'Hello World'); const part = newSummary.getPart(0); expect(part.getTitle()).toBe('Hello World'); }); - it('should correctly set title of second part', function() { + it('should correctly set title of second part', () => { const newSummary = editPartTitle(summary, 1, 'Hello'); const part = newSummary.getPart(1); expect(part.getTitle()).toBe('Hello'); }); - it('should not fail if part doesn\'t exist', function() { + it('should not fail if part doesn\'t exist', () => { const newSummary = editPartTitle(summary, 3, 'Hello'); expect(newSummary.getParts().size).toBe(2); }); }); - diff --git a/packages/gitbook/src/modifiers/summary/__tests__/insertArticle.js b/packages/gitbook/src/modifiers/summary/__tests__/insertArticle.js index d5ae9bc..36c72a1 100644 --- a/packages/gitbook/src/modifiers/summary/__tests__/insertArticle.js +++ b/packages/gitbook/src/modifiers/summary/__tests__/insertArticle.js @@ -1,10 +1,9 @@ const Summary = require('../../../models/summary'); const SummaryArticle = require('../../../models/summaryArticle'); -const File = require('../../../models/file'); -describe('insertArticle', function() { +describe('insertArticle', () => { const insertArticle = require('../insertArticle'); - const summary = Summary.createFromParts(File(), [ + const summary = Summary.createFromParts([ { articles: [ { @@ -42,7 +41,7 @@ describe('insertArticle', function() { } ]); - it('should insert an article at a given level', function() { + it('should insert an article at a given level', () => { const article = SummaryArticle.create({ title: 'Inserted' }, 'fake.level'); @@ -59,7 +58,7 @@ describe('insertArticle', function() { expect(nextOne.getLevel()).toBe('2.1.2'); }); - it('should insert an article in last position', function() { + it('should insert an article in last position', () => { const article = SummaryArticle.create({ title: 'Inserted' }, 'fake.level'); diff --git a/packages/gitbook/src/modifiers/summary/__tests__/insertPart.js b/packages/gitbook/src/modifiers/summary/__tests__/insertPart.js index 5112931..dad7f1e 100644 --- a/packages/gitbook/src/modifiers/summary/__tests__/insertPart.js +++ b/packages/gitbook/src/modifiers/summary/__tests__/insertPart.js @@ -1,11 +1,9 @@ const Summary = require('../../../models/summary'); const SummaryPart = require('../../../models/summaryPart'); -const File = require('../../../models/file'); - -describe('insertPart', function() { +describe('insertPart', () => { const insertPart = require('../insertPart'); - const summary = Summary.createFromParts(File(), [ + const summary = Summary.createFromParts([ { articles: [ { @@ -30,7 +28,7 @@ describe('insertPart', function() { } ]); - it('should insert an part at a given level', function() { + it('should insert an part at a given level', () => { const part = SummaryPart.create({ title: 'Inserted' }, 'meaningless.level'); @@ -46,7 +44,7 @@ describe('insertPart', function() { expect(otherArticle.getLevel()).toBe('3.1'); }); - it('should insert an part in last position', function() { + it('should insert an part in last position', () => { const part = SummaryPart.create({ title: 'Inserted' }, 'meaningless.level'); diff --git a/packages/gitbook/src/modifiers/summary/__tests__/mergeAtLevel.js b/packages/gitbook/src/modifiers/summary/__tests__/mergeAtLevel.js index e0d4a62..94867d3 100644 --- a/packages/gitbook/src/modifiers/summary/__tests__/mergeAtLevel.js +++ b/packages/gitbook/src/modifiers/summary/__tests__/mergeAtLevel.js @@ -1,10 +1,9 @@ const Immutable = require('immutable'); const Summary = require('../../../models/summary'); -const File = require('../../../models/file'); -describe('mergeAtLevel', function() { +describe('mergeAtLevel', () => { const mergeAtLevel = require('../mergeAtLevel'); - const summary = Summary.createFromParts(File(), [ + const summary = Summary.createFromParts([ { articles: [ { @@ -23,7 +22,7 @@ describe('mergeAtLevel', function() { } ]); - it('should edit a part', function() { + it('should edit a part', () => { const beforeChildren = summary.getByLevel('1').getArticles(); const newSummary = mergeAtLevel(summary, '1', {title: 'Part O'}); const edited = newSummary.getByLevel('1'); @@ -33,7 +32,7 @@ describe('mergeAtLevel', function() { expect(Immutable.is(beforeChildren, edited.getArticles())).toBe(true); }); - it('should edit a part', function() { + it('should edit a part', () => { const beforePath = summary.getByLevel('1.2').getPath(); const newSummary = mergeAtLevel(summary, '1.2', {title: 'Renamed article'}); const edited = newSummary.getByLevel('1.2'); diff --git a/packages/gitbook/src/modifiers/summary/__tests__/moveArticle.js b/packages/gitbook/src/modifiers/summary/__tests__/moveArticle.js index a7d111b..ba47404 100644 --- a/packages/gitbook/src/modifiers/summary/__tests__/moveArticle.js +++ b/packages/gitbook/src/modifiers/summary/__tests__/moveArticle.js @@ -1,10 +1,9 @@ const Immutable = require('immutable'); const Summary = require('../../../models/summary'); -const File = require('../../../models/file'); -describe('moveArticle', function() { +describe('moveArticle', () => { const moveArticle = require('../moveArticle'); - const summary = Summary.createFromParts(File(), [ + const summary = Summary.createFromParts([ { articles: [ { @@ -42,13 +41,13 @@ describe('moveArticle', function() { } ]); - it('should move an article to the same place', function() { + it('should move an article to the same place', () => { const newSummary = moveArticle(summary, '2.1', '2.1'); expect(Immutable.is(summary, newSummary)).toBe(true); }); - it('should move an article to an previous level', function() { + it('should move an article to an previous level', () => { const newSummary = moveArticle(summary, '2.2', '2.1'); const moved = newSummary.getByLevel('2.1'); const other = newSummary.getByLevel('2.2'); @@ -57,7 +56,7 @@ describe('moveArticle', function() { expect(other.getTitle()).toBe('2.1'); }); - it('should move an article to a next level', function() { + it('should move an article to a next level', () => { const newSummary = moveArticle(summary, '2.1', '2.2'); const moved = newSummary.getByLevel('2.1'); const other = newSummary.getByLevel('2.2'); diff --git a/packages/gitbook/src/modifiers/summary/__tests__/moveArticleAfter.js b/packages/gitbook/src/modifiers/summary/__tests__/moveArticleAfter.js index 446d8a4..7cccf2b 100644 --- a/packages/gitbook/src/modifiers/summary/__tests__/moveArticleAfter.js +++ b/packages/gitbook/src/modifiers/summary/__tests__/moveArticleAfter.js @@ -1,10 +1,9 @@ const Immutable = require('immutable'); const Summary = require('../../../models/summary'); -const File = require('../../../models/file'); -describe('moveArticleAfter', function() { +describe('moveArticleAfter', () => { const moveArticleAfter = require('../moveArticleAfter'); - const summary = Summary.createFromParts(File(), [ + const summary = Summary.createFromParts([ { articles: [ { @@ -42,19 +41,19 @@ describe('moveArticleAfter', function() { } ]); - it('moving right after itself should be invariant', function() { + it('moving right after itself should be invariant', () => { const newSummary = moveArticleAfter(summary, '2.1', '2.1'); expect(Immutable.is(summary, newSummary)).toBe(true); }); - it('moving after previous one should be invariant too', function() { + it('moving after previous one should be invariant too', () => { const newSummary = moveArticleAfter(summary, '2.1', '2.0'); expect(Immutable.is(summary, newSummary)).toBe(true); }); - it('should move an article after a previous level', function() { + it('should move an article after a previous level', () => { const newSummary = moveArticleAfter(summary, '2.2', '2.0'); const moved = newSummary.getByLevel('2.1'); @@ -62,7 +61,7 @@ describe('moveArticleAfter', function() { expect(newSummary.getByLevel('2.2').getTitle()).toBe('2.1'); }); - it('should move an article after a previous and less deep level', function() { + it('should move an article after a previous and less deep level', () => { const newSummary = moveArticleAfter(summary, '2.1.1', '2.0'); const moved = newSummary.getByLevel('2.1'); @@ -71,7 +70,7 @@ describe('moveArticleAfter', function() { expect(newSummary.getByLevel('2.2').getTitle()).toBe('2.1'); }); - it('should move an article after a next level', function() { + it('should move an article after a next level', () => { const newSummary = moveArticleAfter(summary, '2.1', '2.2'); const moved = newSummary.getByLevel('2.2'); diff --git a/packages/gitbook/src/modifiers/summary/__tests__/removeArticle.js b/packages/gitbook/src/modifiers/summary/__tests__/removeArticle.js index 14587ca..5a016f2 100644 --- a/packages/gitbook/src/modifiers/summary/__tests__/removeArticle.js +++ b/packages/gitbook/src/modifiers/summary/__tests__/removeArticle.js @@ -1,9 +1,8 @@ const Summary = require('../../../models/summary'); -const File = require('../../../models/file'); -describe('removeArticle', function() { +describe('removeArticle', () => { const removeArticle = require('../removeArticle'); - const summary = Summary.createFromParts(File(), [ + const summary = Summary.createFromParts([ { articles: [ { @@ -41,7 +40,7 @@ describe('removeArticle', function() { } ]); - it('should remove an article at a given level', function() { + it('should remove an article at a given level', () => { const newSummary = removeArticle(summary, '2.1.1'); const removed = newSummary.getByLevel('2.1.1'); diff --git a/packages/gitbook/src/modifiers/summary/editPartTitle.js b/packages/gitbook/src/modifiers/summary/editPartTitle.js index ace7058..0a064e1 100644 --- a/packages/gitbook/src/modifiers/summary/editPartTitle.js +++ b/packages/gitbook/src/modifiers/summary/editPartTitle.js @@ -1,13 +1,14 @@ -/** - Edit title of a part in the summary - @param {Summary} summary - @param {Number} index - @param {String} newTitle - @return {Summary} -*/ +/** + * Edit title of a part in the summary + * + * @param {Summary} summary + * @param {Number} index + * @param {String} newTitle + * @return {Summary} + */ function editPartTitle(summary, index, newTitle) { - let parts = summary.getParts(); + let { parts } = summary; let part = parts.get(index); if (!part) { diff --git a/packages/gitbook/src/modifiers/summary/index.js b/packages/gitbook/src/modifiers/summary/index.js index f91fdb6..cb8e8f9 100644 --- a/packages/gitbook/src/modifiers/summary/index.js +++ b/packages/gitbook/src/modifiers/summary/index.js @@ -1,13 +1,16 @@ module.exports = { - insertArticle: require('./insertArticle'), - moveArticle: require('./moveArticle'), - moveArticleAfter: require('./moveArticleAfter'), - removeArticle: require('./removeArticle'), - unshiftArticle: require('./unshiftArticle'), - editArticleTitle: require('./editArticleTitle'), - editArticleRef: require('./editArticleRef'), - - insertPart: require('./insertPart'), - removePart: require('./removePart'), - editPartTitle: require('./editPartTitle') + toDocument: require('./toDocument'), + toText: require('./toText'), + // Articles + insertArticle: require('./insertArticle'), + moveArticle: require('./moveArticle'), + moveArticleAfter: require('./moveArticleAfter'), + removeArticle: require('./removeArticle'), + unshiftArticle: require('./unshiftArticle'), + editArticleTitle: require('./editArticleTitle'), + editArticleRef: require('./editArticleRef'), + // Parts + insertPart: require('./insertPart'), + removePart: require('./removePart'), + editPartTitle: require('./editPartTitle') }; diff --git a/packages/gitbook/src/modifiers/summary/indexArticleLevels.js b/packages/gitbook/src/modifiers/summary/indexArticleLevels.js index 03c26c7..389e195 100644 --- a/packages/gitbook/src/modifiers/summary/indexArticleLevels.js +++ b/packages/gitbook/src/modifiers/summary/indexArticleLevels.js @@ -10,7 +10,7 @@ function indexArticleLevels(article, baseLevel) { baseLevel = baseLevel || article.getLevel(); let articles = article.getArticles(); - articles = articles.map(function(inner, i) { + articles = articles.map((inner, i) => { return indexArticleLevels(inner, baseLevel + '.' + (i + 1)); }); diff --git a/packages/gitbook/src/modifiers/summary/indexPartLevels.js b/packages/gitbook/src/modifiers/summary/indexPartLevels.js index 6e48778..5925fbc 100644 --- a/packages/gitbook/src/modifiers/summary/indexPartLevels.js +++ b/packages/gitbook/src/modifiers/summary/indexPartLevels.js @@ -11,7 +11,7 @@ function indexPartLevels(part, index) { const baseLevel = String(index + 1); let articles = part.getArticles(); - articles = articles.map(function(inner, i) { + articles = articles.map((inner, i) => { return indexArticleLevels(inner, baseLevel + '.' + (i + 1)); }); diff --git a/packages/gitbook/src/modifiers/summary/insertArticle.js b/packages/gitbook/src/modifiers/summary/insertArticle.js index 537f548..f25117b 100644 --- a/packages/gitbook/src/modifiers/summary/insertArticle.js +++ b/packages/gitbook/src/modifiers/summary/insertArticle.js @@ -4,16 +4,16 @@ const mergeAtLevel = require('./mergeAtLevel'); const indexArticleLevels = require('./indexArticleLevels'); /** - Returns a new Summary with the article at the given level, with - subsequent article shifted. - - @param {Summary} summary - @param {Article} article - @param {String|Article} level: level to insert at - @return {Summary} -*/ + * Returns a new Summary with the article at the given level, with + * subsequent article shifted. + * + * @param {Summary} summary + * @param {Article} article + * @param {String|Article} level: level to insert at + * @return {Summary} + */ function insertArticle(summary, article, level) { - article = SummaryArticle(article); + article = new SummaryArticle(article); level = is.string(level) ? level : level.getLevel(); let parent = summary.getParent(level); @@ -36,11 +36,11 @@ function insertArticle(summary, article, level) { } /** - @param {String} - @return {Number} The index of this level within its parent's children + * @param {String} + * @return {Number} The index of this level within its parent's children */ function getLeafIndex(level) { - const arr = level.split('.').map(function(char) { + const arr = level.split('.').map((char) => { return parseInt(char, 10); }); return arr[arr.length - 1] - 1; diff --git a/packages/gitbook/src/modifiers/summary/insertPart.js b/packages/gitbook/src/modifiers/summary/insertPart.js index ea99f89..88750f1 100644 --- a/packages/gitbook/src/modifiers/summary/insertPart.js +++ b/packages/gitbook/src/modifiers/summary/insertPart.js @@ -2,15 +2,15 @@ const SummaryPart = require('../../models/summaryPart'); const indexLevels = require('./indexLevels'); /** - Returns a new Summary with a part inserted at given index - - @param {Summary} summary - @param {Part} part - @param {Number} index - @return {Summary} -*/ + `* Returns a new Summary with a part inserted at given index + `* + `* @param {Summary} summary + `* @param {Part} part + `* @param {Number} index + `* @return {Summary} + */ function insertPart(summary, part, index) { - part = SummaryPart(part); + part = new SummaryPart(part); const parts = summary.getParts().insert(index, part); return indexLevels(summary.set('parts', parts)); diff --git a/packages/gitbook/src/modifiers/summary/mergeAtLevel.js b/packages/gitbook/src/modifiers/summary/mergeAtLevel.js index ea01763..baa5651 100644 --- a/packages/gitbook/src/modifiers/summary/mergeAtLevel.js +++ b/packages/gitbook/src/modifiers/summary/mergeAtLevel.js @@ -8,7 +8,7 @@ @return {List<Article>} */ function editArticleInList(articles, level, newArticle) { - return articles.map(function(article) { + return articles.map((article) => { const articleLevel = article.getLevel(); if (articleLevel === level) { diff --git a/packages/gitbook/src/modifiers/summary/moveArticleAfter.js b/packages/gitbook/src/modifiers/summary/moveArticleAfter.js index a1ed28f..e5da757 100644 --- a/packages/gitbook/src/modifiers/summary/moveArticleAfter.js +++ b/packages/gitbook/src/modifiers/summary/moveArticleAfter.js @@ -38,7 +38,7 @@ function moveArticleAfter(summary, origin, afterTarget) { @return {Array<Number>} */ function levelToArray(l) { - return l.split('.').map(function(char) { + return l.split('.').map((char) => { return parseInt(char, 10); }); } diff --git a/packages/gitbook/src/modifiers/summary/removeArticle.js b/packages/gitbook/src/modifiers/summary/removeArticle.js index 0c4cd33..58ca6c3 100644 --- a/packages/gitbook/src/modifiers/summary/removeArticle.js +++ b/packages/gitbook/src/modifiers/summary/removeArticle.js @@ -17,7 +17,7 @@ function removeArticle(summary, level) { let articles = parent.getArticles(); // Find the index to remove - const index = articles.findIndex(function(art) { + const index = articles.findIndex((art) => { return art.getLevel() === level; }); if (index === -1) { diff --git a/packages/gitbook/src/modifiers/summary/toDocument.js b/packages/gitbook/src/modifiers/summary/toDocument.js new file mode 100644 index 0000000..7cd459a --- /dev/null +++ b/packages/gitbook/src/modifiers/summary/toDocument.js @@ -0,0 +1,94 @@ +const { Document, Block, Inline, Text } = require('slate'); +const { BLOCKS, INLINES } = require('markup-it'); + +/** + * Convert an article in a list item node. + * @param {SummaryArticle} article + * @return {Block} item + */ +function articleToBlock(article) { + const { title, ref, articles } = article; + const text = Text.createFromString(title); + + // Text or link ? + const innerNode = ref ? Inline.create({ + type: INLINES.LINK, + nodes: [ + text + ], + data: { + href: ref + } + }) : text; + + const nodes = [ + Block.create({ + type: BLOCKS.TEXT, + nodes: [ + innerNode + ] + }) + ]; + + if (articles.size > 0) { + nodes.push(articlesToBlock(articles)); + } + + return Block.create({ + type: BLOCKS.LIST_ITEM, + nodes + }); +} + +/** + * Convert a list of articles to a list node. + * @param {List<SummaryArticle>} articles + * @return {Block} list + */ +function articlesToBlock(articles) { + const nodes = articles.map(article => articleToBlock(article)); + return Block.create({ + type: BLOCKS.UL_LIST, + nodes + }); +} + +/** + * Convert a summary to document. + * @param {Summary} summary + * @return {Document} document + */ +function summaryToDocument(summary) { + const { parts } = summary; + const nodes = [ + Block.create({ + type: BLOCKS.HEADING_1, + nodes: [ + Text.createFromString('Summary') + ] + }) + ]; + + parts.forEach((part, i) => { + const { title, articles } = part; + + if (title) { + nodes.push(Block.create({ + type: BLOCKS.HEADING_2, + nodes: [ + Text.createFromString(title) + ] + })); + } else if (i > 0) { + nodes.push(Block.create({ + type: BLOCKS.HR + })); + } + + nodes.push(articlesToBlock(articles)); + }); + + return Document.create({ nodes }); +} + +module.exports = summaryToDocument; diff --git a/packages/gitbook/src/modifiers/summary/toText.js b/packages/gitbook/src/modifiers/summary/toText.js new file mode 100644 index 0000000..176cacd --- /dev/null +++ b/packages/gitbook/src/modifiers/summary/toText.js @@ -0,0 +1,28 @@ +const summaryToDocument = require('./toDocument'); +const parsers = require('../../parsers'); +const error = require('../../utils/error'); + +/** + * Return summary serialized as text. + * @param {Summary} summary + * @param {String} extension? + * @return {String} + */ +function summaryToText(summary, extension) { + const { file } = summary; + const parser = extension ? parsers.getByExt(extension) : file.getParser(); + + if (!parser) { + throw error.FileNotParsableError({ + filename: file.path + }); + } + + // Create a document representing the summary + const document = summaryToDocument(summary); + + // Render the document as text + return parser.toText(document); +} + +module.exports = summaryToText; diff --git a/packages/gitbook/src/modifiers/summary/unshiftArticle.js b/packages/gitbook/src/modifiers/summary/unshiftArticle.js index c5810f0..b9ef4d6 100644 --- a/packages/gitbook/src/modifiers/summary/unshiftArticle.js +++ b/packages/gitbook/src/modifiers/summary/unshiftArticle.js @@ -4,17 +4,17 @@ const SummaryPart = require('../../models/summaryPart'); const indexLevels = require('./indexLevels'); /** - Insert an article at the beginning of summary - - @param {Summary} summary - @param {Article} article - @return {Summary} -*/ + * Insert an article at the beginning of summary + * + * @param {Summary} summary + * @param {Article} article + * @return {Summary} + */ function unshiftArticle(summary, article) { - article = SummaryArticle(article); + article = new SummaryArticle(article); let parts = summary.getParts(); - let part = parts.get(0) || SummaryPart(); + let part = parts.get(0) || new SummaryPart(); let articles = part.getArticles(); articles = articles.unshift(article); diff --git a/packages/gitbook/src/output/__tests__/createMock.js b/packages/gitbook/src/output/__tests__/createMock.js index 09b93da..1d0a9a9 100644 --- a/packages/gitbook/src/output/__tests__/createMock.js +++ b/packages/gitbook/src/output/__tests__/createMock.js @@ -24,7 +24,7 @@ function createMockOutput(generator, files, options) { options = generator.Options(options); return parseBook(book) - .then(function(resultBook) { + .then((resultBook) => { return new Output({ book: resultBook, options, diff --git a/packages/gitbook/src/output/__tests__/ebook.js b/packages/gitbook/src/output/__tests__/ebook.js index 8b7096c..1fb8d94 100644 --- a/packages/gitbook/src/output/__tests__/ebook.js +++ b/packages/gitbook/src/output/__tests__/ebook.js @@ -1,15 +1,15 @@ const generateMock = require('./generateMock'); const EbookGenerator = require('../ebook'); -describe('EbookGenerator', function() { +describe('EbookGenerator', () => { - it('should generate a SUMMARY.html', function() { + /* it('should generate a SUMMARY.html', () => { return generateMock(EbookGenerator, { 'README.md': 'Hello World' }) - .then(function(folder) { + .then((folder) => { expect(folder).toHaveFile('SUMMARY.html'); expect(folder).toHaveFile('index.html'); }); - }); + });*/ }); diff --git a/packages/gitbook/src/output/__tests__/json.js b/packages/gitbook/src/output/__tests__/json.js index d4992ec..92be019 100644 --- a/packages/gitbook/src/output/__tests__/json.js +++ b/packages/gitbook/src/output/__tests__/json.js @@ -1,18 +1,18 @@ const generateMock = require('./generateMock'); const JSONGenerator = require('../json'); -describe('JSONGenerator', function() { +describe('JSONGenerator', () => { - it('should generate a README.json', function() { + it('should generate a README.json', () => { return generateMock(JSONGenerator, { 'README.md': 'Hello World' }) - .then(function(folder) { + .then((folder) => { expect(folder).toHaveFile('README.json'); }); }); - it('should generate a json file for each articles', function() { + it('should generate a json file for each articles', () => { return generateMock(JSONGenerator, { 'README.md': 'Hello World', 'SUMMARY.md': '# Summary\n\n* [Page](test/page.md)', @@ -20,13 +20,13 @@ describe('JSONGenerator', function() { 'page.md': 'Hello 2' } }) - .then(function(folder) { + .then((folder) => { expect(folder).toHaveFile('README.json'); expect(folder).toHaveFile('test/page.json'); }); }); - it('should generate a multilingual book', function() { + it('should generate a multilingual book', () => { return generateMock(JSONGenerator, { 'LANGS.md': '# Languages\n\n* [en](en)\n* [fr](fr)', 'en': { @@ -36,7 +36,7 @@ describe('JSONGenerator', function() { 'README.md': 'Bonjour' } }) - .then(function(folder) { + .then((folder) => { expect(folder).toHaveFile('en/README.json'); expect(folder).toHaveFile('fr/README.json'); expect(folder).toHaveFile('README.json'); diff --git a/packages/gitbook/src/output/__tests__/website.js b/packages/gitbook/src/output/__tests__/website.js index 4c10f1e..ab96635 100644 --- a/packages/gitbook/src/output/__tests__/website.js +++ b/packages/gitbook/src/output/__tests__/website.js @@ -77,7 +77,7 @@ describe('WebsiteGenerator', () => { return generateMock(WebsiteGenerator, { 'README.adoc': 'Hello World' }) - .then(function(folder) { + .then((folder) => { expect(folder).toHaveFile('index.html'); }); }); @@ -90,7 +90,7 @@ describe('WebsiteGenerator', () => { 'page.md': 'Hello 2' } }) - .then(function(folder) { + .then((folder) => { expect(folder).toHaveFile('index.html'); expect(folder).toHaveFile('test/page.html'); }); diff --git a/packages/gitbook/src/output/callHook.js b/packages/gitbook/src/output/callHook.js index 34c16ab..8ebc189 100644 --- a/packages/gitbook/src/output/callHook.js +++ b/packages/gitbook/src/output/callHook.js @@ -38,8 +38,8 @@ function callHook(name, getArgument, handleResult, output) { Promise(getArgument(output)) // Call the hooks in serie - .then(function(arg) { - return Promise.reduce(plugins, function(prev, plugin) { + .then((arg) => { + return Promise.reduce(plugins, (prev, plugin) => { const hook = plugin.getHook(name); if (!hook) { return prev; @@ -50,7 +50,7 @@ function callHook(name, getArgument, handleResult, output) { }) // Handle final result - .then(function(result) { + .then((result) => { output = Api.decodeGlobal(output, context); return handleResult(output, result); }) diff --git a/packages/gitbook/src/output/callPageHook.js b/packages/gitbook/src/output/callPageHook.js index 0c7adfa..f68e4a3 100644 --- a/packages/gitbook/src/output/callPageHook.js +++ b/packages/gitbook/src/output/callPageHook.js @@ -13,11 +13,11 @@ function callPageHook(name, output, page) { return callHook( name, - function(out) { + (out) => { return Api.encodePage(out, page); }, - function(out, result) { + (out, result) => { return Api.decodePage(out, page, result); }, diff --git a/packages/gitbook/src/output/ebook/getConvertOptions.js b/packages/gitbook/src/output/ebook/getConvertOptions.js index b37c68e..882bc06 100644 --- a/packages/gitbook/src/output/ebook/getConvertOptions.js +++ b/packages/gitbook/src/output/ebook/getConvertOptions.js @@ -18,7 +18,7 @@ function getConvertOptions(output) { const config = book.getConfig(); return Promise() - .then(function() { + .then(() => { const coverPath = getCoverPath(output); let options = { '--cover': coverPath, @@ -47,7 +47,7 @@ function getConvertOptions(output) { getPDFTemplate(output, 'header'), getPDFTemplate(output, 'footer') ]) - .spread(function(headerTpl, footerTpl) { + .spread((headerTpl, footerTpl) => { const pdfOptions = config.getValue('pdf').toJS(); return options = extend(options, { diff --git a/packages/gitbook/src/output/ebook/onFinish.js b/packages/gitbook/src/output/ebook/onFinish.js index 7db757f..6634f0b 100644 --- a/packages/gitbook/src/output/ebook/onFinish.js +++ b/packages/gitbook/src/output/ebook/onFinish.js @@ -45,7 +45,7 @@ function runEbookConvert(output) { } return getConvertOptions(output) - .then(function(options) { + .then((options) => { const cmd = [ 'ebook-convert', path.resolve(outputFolder, SUMMARY_FILE), @@ -54,10 +54,10 @@ function runEbookConvert(output) { ].join(' '); return command.exec(cmd) - .progress(function(data) { + .progress((data) => { logger.debug(data); }) - .fail(function(err) { + .fail((err) => { if (err.code == 127) { throw error.RequireInstallError({ cmd: 'ebook-convert', diff --git a/packages/gitbook/src/output/ebook/onPage.js b/packages/gitbook/src/output/ebook/onPage.js index a7c2137..a09a67f 100644 --- a/packages/gitbook/src/output/ebook/onPage.js +++ b/packages/gitbook/src/output/ebook/onPage.js @@ -17,7 +17,7 @@ function onPage(output, page) { ]) // Write page using website generator - .then(function(resultPage) { + .then((resultPage) => { return WebsiteGenerator.onPage(output, resultPage); }); } diff --git a/packages/gitbook/src/output/generateAssets.js b/packages/gitbook/src/output/generateAssets.js index f926492..23ec295 100644 --- a/packages/gitbook/src/output/generateAssets.js +++ b/packages/gitbook/src/output/generateAssets.js @@ -16,7 +16,7 @@ function generateAssets(generator, output) { return Promise(output); } - return Promise.reduce(assets, function(out, assetFile) { + return Promise.reduce(assets, (out, assetFile) => { logger.debug.ln('copy asset "' + assetFile + '"'); return generator.onAsset(out, assetFile); diff --git a/packages/gitbook/src/output/generateBook.js b/packages/gitbook/src/output/generateBook.js index 0e2c230..dbf54dc 100644 --- a/packages/gitbook/src/output/generateBook.js +++ b/packages/gitbook/src/output/generateBook.js @@ -28,14 +28,14 @@ function processOutput(generator, startOutput) { .then( callHook.bind(null, 'config', - function(output) { + (output) => { const book = output.getBook(); const config = book.getConfig(); const values = config.getValues(); return values.toJS(); }, - function(output, result) { + (output, result) => { let book = output.getBook(); let config = book.getConfig(); @@ -49,10 +49,10 @@ function processOutput(generator, startOutput) { .then( callHook.bind(null, 'init', - function(output) { + (output) => { return {}; }, - function(output) { + (output) => { return output; } ) @@ -83,7 +83,7 @@ function processOutput(generator, startOutput) { const state = output.getState(); const options = output.getOptions(); - return Promise.forEach(books, function(langBook) { + return Promise.forEach(books, (langBook) => { // Inherits plugins list, options and state const langOptions = options.set('root', path.join(outputRoot, langBook.getLanguage())); const langOutput = new Output({ @@ -102,10 +102,10 @@ function processOutput(generator, startOutput) { .then(callHook.bind(null, 'finish:before', - function(output) { + (output) => { return {}; }, - function(output) { + (output) => { return output; } ) @@ -121,10 +121,10 @@ function processOutput(generator, startOutput) { .then(callHook.bind(null, 'finish', - function(output) { + (output) => { return {}; }, - function(output) { + (output) => { return output; } ) diff --git a/packages/gitbook/src/output/generatePage.js b/packages/gitbook/src/output/generatePage.js index 7375f1d..38cd450 100644 --- a/packages/gitbook/src/output/generatePage.js +++ b/packages/gitbook/src/output/generatePage.js @@ -23,10 +23,9 @@ function generatePage(output, page) { return timing.measure( 'page.generate', Promise(page) - .then(function(resultPage) { + .then((resultPage) => { const file = resultPage.getFile(); - const filePath = file.getPath(); - const parser = file.getParser(); + const { path: filePath, parser } = file; const context = JSONUtils.encodeState(output, resultPage); if (!parser) { @@ -39,8 +38,8 @@ function generatePage(output, page) { return callPageHook('page:before', output, resultPage) // Escape code blocks with raw tags - .then((currentPage) => { - return parser.preparePage(currentPage.getContent()); + .then(({ content }) => { + return parser.prepare(content); }) // Render templating syntax @@ -49,11 +48,9 @@ function generatePage(output, page) { return Templating.render(engine, absoluteFilePath, content, context); }) - // Parse with markdown/asciidoc parser - .then((content) => parser.parsePage(content)) - - // Return new page - .then(({content}) => { + // Render with markdown/asciidoc parser + .then((content) => { + content = parser.toHTML(content); return resultPage.set('content', content); }) diff --git a/packages/gitbook/src/output/generatePages.js b/packages/gitbook/src/output/generatePages.js index 21b6610..8ea15ab 100644 --- a/packages/gitbook/src/output/generatePages.js +++ b/packages/gitbook/src/output/generatePages.js @@ -17,16 +17,16 @@ function generatePages(generator, output) { return Promise(output); } - return Promise.reduce(pages, function(out, page) { + return Promise.reduce(pages, (out, page) => { const file = page.getFile(); logger.debug.ln('generate page "' + file.getPath() + '"'); return generatePage(out, page) - .then(function(resultPage) { + .then((resultPage) => { return generator.onPage(out, resultPage); }) - .fail(function(err) { + .fail((err) => { logger.error.ln('error while generating page "' + file.getPath() + '":'); throw err; }); diff --git a/packages/gitbook/src/output/helper/writeFile.js b/packages/gitbook/src/output/helper/writeFile.js index 01a8e68..ab36418 100644 --- a/packages/gitbook/src/output/helper/writeFile.js +++ b/packages/gitbook/src/output/helper/writeFile.js @@ -14,7 +14,7 @@ function writeFile(output, filePath, content) { filePath = path.join(rootFolder, filePath); return fs.ensureFile(filePath) - .then(function() { + .then(() => { return fs.writeFile(filePath, content); }) .thenResolve(output); diff --git a/packages/gitbook/src/output/index.js b/packages/gitbook/src/output/index.js index 574b3df..6ef3b85 100644 --- a/packages/gitbook/src/output/index.js +++ b/packages/gitbook/src/output/index.js @@ -13,7 +13,7 @@ const generators = Immutable.List([ @return {Generator} */ function getGenerator(name) { - return generators.find(function(generator) { + return generators.find((generator) => { return generator.name == name; }); } diff --git a/packages/gitbook/src/output/json/onFinish.js b/packages/gitbook/src/output/json/onFinish.js index 24f5159..3fe01a3 100644 --- a/packages/gitbook/src/output/json/onFinish.js +++ b/packages/gitbook/src/output/json/onFinish.js @@ -27,15 +27,15 @@ function onFinish(output) { return fs.readFile(path.resolve(outputRoot, mainLanguage.getID(), 'README.json'), 'utf8') // Extend the JSON - .then(function(content) { + .then((content) => { const json = JSON.parse(content); - json.languages = JSONUtils.encodeLanguages(languages, urls); + json.languages = JSONUtils.encodeLanguages(languages, null, urls); return json; }) - .then(function(json) { + .then((json) => { return fs.writeFile( path.resolve(outputRoot, 'README.json'), JSON.stringify(json, null, 4) diff --git a/packages/gitbook/src/output/json/onPage.js b/packages/gitbook/src/output/json/onPage.js index f31fadc..bcd76ee 100644 --- a/packages/gitbook/src/output/json/onPage.js +++ b/packages/gitbook/src/output/json/onPage.js @@ -17,7 +17,7 @@ function onPage(output, page) { const readme = output.getBook().getReadme().getFile(); return Modifiers.modifyHTML(page, getModifiers(output, page)) - .then(function(resultPage) { + .then((resultPage) => { // Generate the JSON const json = JSONUtils.encodeState(output, resultPage); diff --git a/packages/gitbook/src/output/modifiers/__tests__/addHeadingId.js b/packages/gitbook/src/output/modifiers/__tests__/addHeadingId.js index 4d77e75..10ff10f 100644 --- a/packages/gitbook/src/output/modifiers/__tests__/addHeadingId.js +++ b/packages/gitbook/src/output/modifiers/__tests__/addHeadingId.js @@ -1,22 +1,22 @@ const cheerio = require('cheerio'); const addHeadingId = require('../addHeadingId'); -describe('addHeadingId', function() { - it('should add an ID if none', function() { +describe('addHeadingId', () => { + it('should add an ID if none', () => { const $ = cheerio.load('<h1>Hello World</h1><h2>Cool !!</h2>'); return addHeadingId($) - .then(function() { + .then(() => { const html = $.html(); expect(html).toBe('<h1 id="hello-world">Hello World</h1><h2 id="cool-">Cool !!</h2>'); }); }); - it('should not change existing IDs', function() { + it('should not change existing IDs', () => { const $ = cheerio.load('<h1 id="awesome">Hello World</h1>'); return addHeadingId($) - .then(function() { + .then(() => { const html = $.html(); expect(html).toBe('<h1 id="awesome">Hello World</h1>'); }); diff --git a/packages/gitbook/src/output/modifiers/__tests__/annotateText.js b/packages/gitbook/src/output/modifiers/__tests__/annotateText.js index 28a5cc5..8e7b96e 100644 --- a/packages/gitbook/src/output/modifiers/__tests__/annotateText.js +++ b/packages/gitbook/src/output/modifiers/__tests__/annotateText.js @@ -3,13 +3,13 @@ const cheerio = require('cheerio'); const GlossaryEntry = require('../../../models/glossaryEntry'); const annotateText = require('../annotateText'); -describe('annotateText', function() { +describe('annotateText', () => { const entries = Immutable.List([ - GlossaryEntry({ name: 'Word' }), - GlossaryEntry({ name: 'Multiple Words' }) + new GlossaryEntry({ name: 'Word' }), + new GlossaryEntry({ name: 'Multiple Words' }) ]); - it('should annotate text', function() { + it('should annotate text', () => { const $ = cheerio.load('<p>This is a word, and multiple words</p>'); annotateText(entries, 'GLOSSARY.md', $); @@ -28,18 +28,17 @@ describe('annotateText', function() { expect(words.hasClass('glossary-term')).toBeTruthy(); }); - it('should not annotate scripts', function() { + it('should not annotate scripts', () => { const $ = cheerio.load('<script>This is a word, and multiple words</script>'); annotateText(entries, 'GLOSSARY.md', $); expect($('a').length).toBe(0); }); - it('should not annotate when has class "no-glossary"', function() { + it('should not annotate when has class "no-glossary"', () => { const $ = cheerio.load('<p class="no-glossary">This is a word, and multiple words</p>'); annotateText(entries, 'GLOSSARY.md', $); expect($('a').length).toBe(0); }); }); - diff --git a/packages/gitbook/src/output/modifiers/__tests__/fetchRemoteImages.js b/packages/gitbook/src/output/modifiers/__tests__/fetchRemoteImages.js index 9145cae..435e27d 100644 --- a/packages/gitbook/src/output/modifiers/__tests__/fetchRemoteImages.js +++ b/packages/gitbook/src/output/modifiers/__tests__/fetchRemoteImages.js @@ -4,19 +4,19 @@ const path = require('path'); const URL = 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/280px-PNG_transparency_demonstration_1.png'; -describe('fetchRemoteImages', function() { +describe('fetchRemoteImages', () => { let dir; const fetchRemoteImages = require('../fetchRemoteImages'); - beforeEach(function() { + beforeEach(() => { dir = tmp.dirSync(); }); - it('should download image file', function() { + it('should download image file', () => { const $ = cheerio.load('<img src="' + URL + '" />'); return fetchRemoteImages(dir.name, 'index.html', $) - .then(function() { + .then(() => { const $img = $('img'); const src = $img.attr('src'); @@ -24,11 +24,11 @@ describe('fetchRemoteImages', function() { }); }); - it('should download image file and replace with relative path', function() { + it('should download image file and replace with relative path', () => { const $ = cheerio.load('<img src="' + URL + '" />'); return fetchRemoteImages(dir.name, 'test/index.html', $) - .then(function() { + .then(() => { const $img = $('img'); const src = $img.attr('src'); diff --git a/packages/gitbook/src/output/modifiers/__tests__/inlinePng.js b/packages/gitbook/src/output/modifiers/__tests__/inlinePng.js index fd031b0..40ad042 100644 --- a/packages/gitbook/src/output/modifiers/__tests__/inlinePng.js +++ b/packages/gitbook/src/output/modifiers/__tests__/inlinePng.js @@ -2,18 +2,18 @@ const cheerio = require('cheerio'); const tmp = require('tmp'); const inlinePng = require('../inlinePng'); -describe('inlinePng', function() { +describe('inlinePng', () => { let dir; - beforeEach(function() { + beforeEach(() => { dir = tmp.dirSync(); }); - it('should write an inline PNG using data URI as a file', function() { + it('should write an inline PNG using data URI as a file', () => { const $ = cheerio.load('<img alt="GitBook Logo 20x20" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUEAYAAADdGcFOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsTAAALEwEAmpwYAAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpMwidZAAAF+klEQVRIDY3Wf5CVVR3H8c9z791fyI9dQwdQ4TTI7wEWnQZZAa/mJE4Z0OaKUuN1KoaykZxUGGHay+iIVFMoEYrUPhDCKEKW2ChT8dA0RCSxWi6EW3sYYpcfxq5C+4O9957O+7m7O/qHQ9/XzH1+nHuec57z8wkWTsKw0y6N/LxXN6KzTnEUHi8eP/l3YStSU/MdsYvBbGh8six2YXcbcgc++QkfTQkWz/81KtqDA0hlUoWnsX+5uxe5X365BB9my2bjrHNHccLk16BpS9CExjcmXMDbD6wehdyEjxbjz1uK1zn9qga6dcfnMLXeXY/qjuQqTF4W1MKke8ZgeNhjMCxMPIWSd4OF78C55CFI/1kF6WwXpMqjkAZ/CKniNDrCsmU4lE1YbPlgR2x7R39FF23D4mq3A1+Z35PGTNs1E1XhxcGQOh6HNPwXkK56BVJhOaRg/pvoHXNxHFw410B25EYE2RMvI0i/twFJvXcrFObykEa+DmnQGLwYqR0l2a6JqItaj8C/4E2QxtZCofkC8tF1t8HZc/fAZaLnIF2xEsoEtW1w7vBSSFtfhDTnCki9cSi81Ain1uko2Ld+Dmf2rkUq0/5t+PYbFtPQdkjzNiAXTWtDEF49FgkzJInAVPwNyhzcDOmrdZCm/Rn+ebWtcPs+/U24hmg2XL0rRkPPELh9R8fDtXR2oC/VuZbGaci79Ajkb6lZgfyYtyzy/X9s6T/pO/ZfN/RdNxxIwTWM2wbX8KVmuIaEqmKm6zEondwGpd0SyOy5DrJ//TFkX9kMhd3XQHbEVCSsm4OECV5HIv2p15CwfWPSntoHRbv2Q1HzSvSlSqZwATIuBxk/zZBOBbdB+u9hSKU3Q7pwAjInZkFm6U8hu7MSMqe/Dqn8fUj5GVCmpxK+4N/F1LMa0p5eSOPqIPP7NGSunAI/+R6GnzQzIBt8A1LC/QZ+6HwLst1rITv0n5CtXgSZ78yFTNkR+FdeDZneJkip3fAtsQ5Scilkek7CH9dAmjIWvkK7IXXOh6/IzZDNPQdZXR1TQmdjKv0ZfEu0YKDpNflpyG5aDtnRv8VAuu3dBV+huyBbvgdS97tQNLQc0mfugKy5Cb4BipPIXvsUpK5N8Mvao/Bd3QDZRH9Rrtj3Cl6FHwPFMLmNkKrj8BnHoT+XX6f2wl+XxFS4Ab7C72Dgf7bi+5DpTkNm8kQMpCs/BzIlz8LfPxnzLdh3EjwMX4GX4Ju4GNb9A1L7k/D3J8b6kv2LFCtmCmcgUzoJsr2z4MfwFsh87xikZefg188fYaAhpPUxm3ge/vFnYkoED0HqeQiyJYcwkNGWnoNv6s9C1p1Bf/389VYoCjohW7UfMms3wXdpBv7+FEiPLIHs4DIMNERUNhbSpY3wk6QOsqlCDVx2xCrInMpBmfNPQOnzKxBkkrugdOl9GKigSZZCUWIm/GqwDtLUI5D+WAOlb9wKP0YvQLbjZSjsaYaL/n0/FA3fDtnCGihK5UYjCK+ZDr+TDIKLdm2Fs1UOzo76F5wO74XSZj0S6d7RCMLkCshcXALZxaWQRjXDZQ62oRAdCeG/Ju5HELX2QFH3C0hkRy6GovyfwF58AoVbguOxyB2H7/I34Gf11yANnQSp7Vr4MbQH0vg7kbNNp5AM3UrIVDchnz56B1Jm573wW9gZSFVPwO/hefg5FsIvN09CchtQCIOFw/F5U8ii3CZn4cqo7C8YlXEPYkx9cacZl00+iwnprrtwVdj1Q/gXmAs/pu6LZc9XQOGgSvh19n2cDZN341g2EcfxTEGwH/RewqlMsUfbbWIGLjUG+j/j9nokD1beiOvLS5dhjr30Gu6ZnivgdtM/6VJvY1+6pBHbH+h9CX84vfMxNJtisYVFlys+WNCIZJNmIsjohlhNSQC3f8R55H+y/hjkN8GPR9ndCLJxT4/3n0Px51ay8XQnNrYfDJHf//Fc0oMrEZSeeQGJ7+Z+gKCgLbHNWgXnB9FlYt5JaN38JIINC95EakjtAqQeuUx21c5B6tEFf0fSfbEFQf28Z6D6y+X/H0jf40QQJhYwAAAAAElFTkSuQmCC"/>'); return inlinePng(dir.name, 'index.html', $) - .then(function() { + .then(() => { const $img = $('img'); const src = $img.attr('src'); diff --git a/packages/gitbook/src/output/modifiers/__tests__/resolveLinks.js b/packages/gitbook/src/output/modifiers/__tests__/resolveLinks.js index d11a31f..7ee3193 100644 --- a/packages/gitbook/src/output/modifiers/__tests__/resolveLinks.js +++ b/packages/gitbook/src/output/modifiers/__tests__/resolveLinks.js @@ -11,7 +11,7 @@ describe('resolveLinks', () => { const $ = cheerio.load(TEST); return resolveLinks(resolveFileBasic, $) - .then(function() { + .then(() => { const link = $('a'); expect(link.attr('href')).toBe('fakeDir/test/cool.md'); }); @@ -24,7 +24,7 @@ describe('resolveLinks', () => { const $ = cheerio.load(TEST); return resolveLinks(resolveFileBasic, $) - .then(function() { + .then(() => { const link = $('a'); expect(link.attr('target')).toBe('_blank'); }); diff --git a/packages/gitbook/src/output/modifiers/__tests__/svgToImg.js b/packages/gitbook/src/output/modifiers/__tests__/svgToImg.js index 4bdab59..ed43de8 100644 --- a/packages/gitbook/src/output/modifiers/__tests__/svgToImg.js +++ b/packages/gitbook/src/output/modifiers/__tests__/svgToImg.js @@ -1,19 +1,19 @@ const cheerio = require('cheerio'); const tmp = require('tmp'); -describe('svgToImg', function() { +describe('svgToImg', () => { let dir; const svgToImg = require('../svgToImg'); - beforeEach(function() { + beforeEach(() => { dir = tmp.dirSync(); }); - it('should write svg as a file', function() { + it('should write svg as a file', () => { const $ = cheerio.load('<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" version="1.1"><rect width="200" height="100" stroke="black" stroke-width="6" fill="green"/></svg>'); return svgToImg(dir.name, 'index.html', $) - .then(function() { + .then(() => { const $img = $('img'); const src = $img.attr('src'); diff --git a/packages/gitbook/src/output/modifiers/__tests__/svgToPng.js b/packages/gitbook/src/output/modifiers/__tests__/svgToPng.js index 0a12938..003fe6b 100644 --- a/packages/gitbook/src/output/modifiers/__tests__/svgToPng.js +++ b/packages/gitbook/src/output/modifiers/__tests__/svgToPng.js @@ -5,22 +5,22 @@ const path = require('path'); const svgToImg = require('../svgToImg'); const svgToPng = require('../svgToPng'); -describe('svgToPng', function() { +describe('svgToPng', () => { let dir; - beforeEach(function() { + beforeEach(() => { dir = tmp.dirSync(); }); - it('should write svg as png file', function() { + it('should write svg as png file', () => { const $ = cheerio.load('<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" version="1.1"><rect width="200" height="100" stroke="black" stroke-width="6" fill="green"/></svg>'); const fileName = 'index.html'; return svgToImg(dir.name, fileName, $) - .then(function() { + .then(() => { return svgToPng(dir.name, fileName, $); }) - .then(function() { + .then(() => { const $img = $('img'); const src = $img.attr('src'); diff --git a/packages/gitbook/src/output/modifiers/annotateText.js b/packages/gitbook/src/output/modifiers/annotateText.js index 36ee4e9..98350cd 100644 --- a/packages/gitbook/src/output/modifiers/annotateText.js +++ b/packages/gitbook/src/output/modifiers/annotateText.js @@ -63,7 +63,7 @@ function replaceText($, el, search, replace, text_only) { * @param {HTMLDom} $ */ function annotateText(entries, glossaryFilePath, $) { - entries.forEach(function(entry) { + entries.forEach((entry) => { const entryId = entry.getID(); const name = entry.getName(); const description = entry.getDescription(); @@ -77,7 +77,7 @@ function annotateText(entries, glossaryFilePath, $) { $this.parents(ANNOTATION_IGNORE).length > 0 ) return; - replaceText($, this, searchRegex, function(match) { + replaceText($, this, searchRegex, (match) => { return '<a href="/' + glossaryFilePath + '#' + entryId + '" ' + 'class="glossary-term" title="' + escape(description) + '">' + match diff --git a/packages/gitbook/src/output/modifiers/editHTMLElement.js b/packages/gitbook/src/output/modifiers/editHTMLElement.js index d0d2b19..f2acc55 100644 --- a/packages/gitbook/src/output/modifiers/editHTMLElement.js +++ b/packages/gitbook/src/output/modifiers/editHTMLElement.js @@ -6,7 +6,7 @@ const Promise = require('../../utils/promise'); function editHTMLElement($, selector, fn) { const $elements = $(selector); - return Promise.forEach($elements, function(el) { + return Promise.forEach($elements, (el) => { const $el = $(el); return fn($el); }); diff --git a/packages/gitbook/src/output/modifiers/fetchRemoteImages.js b/packages/gitbook/src/output/modifiers/fetchRemoteImages.js index f022093..b380c62 100644 --- a/packages/gitbook/src/output/modifiers/fetchRemoteImages.js +++ b/packages/gitbook/src/output/modifiers/fetchRemoteImages.js @@ -16,7 +16,7 @@ const LocationUtils = require('../../utils/location'); function fetchRemoteImages(rootFolder, currentFile, $) { const currentDirectory = path.dirname(currentFile); - return editHTMLElement($, 'img', function($img) { + return editHTMLElement($, 'img', ($img) => { let src = $img.attr('src'); const extension = path.extname(src); @@ -29,10 +29,10 @@ function fetchRemoteImages(rootFolder, currentFile, $) { const fileName = hash + extension; const filePath = path.join(rootFolder, fileName); - return fs.assertFile(filePath, function() { + return fs.assertFile(filePath, () => { return fs.download(src, filePath); }) - .then(function() { + .then(() => { // Convert to relative src = LocationUtils.relative(currentDirectory, fileName); diff --git a/packages/gitbook/src/output/modifiers/inlinePng.js b/packages/gitbook/src/output/modifiers/inlinePng.js index bf14e4f..1a27573 100644 --- a/packages/gitbook/src/output/modifiers/inlinePng.js +++ b/packages/gitbook/src/output/modifiers/inlinePng.js @@ -17,7 +17,7 @@ const editHTMLElement = require('./editHTMLElement'); function inlinePng(rootFolder, currentFile, $) { const currentDirectory = path.dirname(currentFile); - return editHTMLElement($, 'img', function($img) { + return editHTMLElement($, 'img', ($img) => { const src = $img.attr('src'); if (!LocationUtils.isDataURI(src)) { return; @@ -30,10 +30,10 @@ function inlinePng(rootFolder, currentFile, $) { // Result file path const filePath = path.join(rootFolder, fileName); - return fs.assertFile(filePath, function() { + return fs.assertFile(filePath, () => { return imagesUtil.convertInlinePNG(src, filePath); }) - .then(function() { + .then(() => { // Convert filename to a relative filename fileName = LocationUtils.relative(currentDirectory, fileName); diff --git a/packages/gitbook/src/output/modifiers/modifyHTML.js b/packages/gitbook/src/output/modifiers/modifyHTML.js index 64abd07..b866814 100644 --- a/packages/gitbook/src/output/modifiers/modifyHTML.js +++ b/packages/gitbook/src/output/modifiers/modifyHTML.js @@ -13,10 +13,10 @@ function modifyHTML(page, operations) { const html = page.getContent(); const $ = cheerio.load(html); - return Promise.forEach(operations, function(op) { + return Promise.forEach(operations, (op) => { return op($); }) - .then(function() { + .then(() => { const resultHTML = $.html(); return page.set('content', resultHTML); }); diff --git a/packages/gitbook/src/output/modifiers/resolveImages.js b/packages/gitbook/src/output/modifiers/resolveImages.js index c647fde..b3a0ce6 100644 --- a/packages/gitbook/src/output/modifiers/resolveImages.js +++ b/packages/gitbook/src/output/modifiers/resolveImages.js @@ -13,7 +13,7 @@ const editHTMLElement = require('./editHTMLElement'); function resolveImages(currentFile, $) { const currentDirectory = path.dirname(currentFile); - return editHTMLElement($, 'img', function($img) { + return editHTMLElement($, 'img', ($img) => { let src = $img.attr('src'); if (LocationUtils.isExternal(src) || LocationUtils.isDataURI(src)) { diff --git a/packages/gitbook/src/output/modifiers/resolveLinks.js b/packages/gitbook/src/output/modifiers/resolveLinks.js index ca81ccb..94de55d 100644 --- a/packages/gitbook/src/output/modifiers/resolveLinks.js +++ b/packages/gitbook/src/output/modifiers/resolveLinks.js @@ -9,7 +9,7 @@ const editHTMLElement = require('./editHTMLElement'); * @param {HTMLDom} $ */ function resolveLinks(resolveURL, $) { - return editHTMLElement($, 'a', function($a) { + return editHTMLElement($, 'a', ($a) => { let href = $a.attr('href'); // Don't change a tag without href diff --git a/packages/gitbook/src/output/modifiers/svgToImg.js b/packages/gitbook/src/output/modifiers/svgToImg.js index ac37d07..36b8534 100644 --- a/packages/gitbook/src/output/modifiers/svgToImg.js +++ b/packages/gitbook/src/output/modifiers/svgToImg.js @@ -31,7 +31,7 @@ function renderDOM($, dom, options) { function svgToImg(baseFolder, currentFile, $) { const currentDirectory = path.dirname(currentFile); - return editHTMLElement($, 'svg', function($svg) { + return editHTMLElement($, 'svg', ($svg) => { const content = '<?xml version="1.0" encoding="UTF-8"?>' + renderDOM($, $svg); @@ -41,12 +41,12 @@ function svgToImg(baseFolder, currentFile, $) { const filePath = path.join(baseFolder, fileName); // Write the svg to the file - return fs.assertFile(filePath, function() { + return fs.assertFile(filePath, () => { return fs.writeFile(filePath, content, 'utf8'); }) // Return as image - .then(function() { + .then(() => { const src = LocationUtils.relative(currentDirectory, fileName); $svg.replaceWith('<img src="' + src + '" />'); }); diff --git a/packages/gitbook/src/output/modifiers/svgToPng.js b/packages/gitbook/src/output/modifiers/svgToPng.js index ad3f31f..0998a86 100644 --- a/packages/gitbook/src/output/modifiers/svgToPng.js +++ b/packages/gitbook/src/output/modifiers/svgToPng.js @@ -17,7 +17,7 @@ const editHTMLElement = require('./editHTMLElement'); function svgToPng(rootFolder, currentFile, $) { const currentDirectory = path.dirname(currentFile); - return editHTMLElement($, 'img', function($img) { + return editHTMLElement($, 'img', ($img) => { let src = $img.attr('src'); if (path.extname(src) !== '.svg') { return; @@ -36,10 +36,10 @@ function svgToPng(rootFolder, currentFile, $) { // Result file path const filePath = path.join(rootFolder, fileName); - return fs.assertFile(filePath, function() { + return fs.assertFile(filePath, () => { return imagesUtil.convertSVGToPNG(inputPath, filePath); }) - .then(function() { + .then(() => { // Convert filename to a relative filename fileName = LocationUtils.relative(currentDirectory, fileName); diff --git a/packages/gitbook/src/output/prepareAssets.js b/packages/gitbook/src/output/prepareAssets.js index 2851b01..88c41f6 100644 --- a/packages/gitbook/src/output/prepareAssets.js +++ b/packages/gitbook/src/output/prepareAssets.js @@ -12,7 +12,7 @@ function prepareAssets(output) { const logger = output.getLogger(); return Parse.listAssets(book, pages) - .then(function(assets) { + .then((assets) => { logger.info.ln('found', assets.size, 'asset files'); return output.set('assets', assets); diff --git a/packages/gitbook/src/output/preparePlugins.js b/packages/gitbook/src/output/preparePlugins.js index c84bade..cb6b4ab 100644 --- a/packages/gitbook/src/output/preparePlugins.js +++ b/packages/gitbook/src/output/preparePlugins.js @@ -13,7 +13,7 @@ function preparePlugins(output) { return Promise() // Only load plugins for main book - .then(function() { + .then(() => { if (book.isLanguageBook()) { return output.getPlugins(); } else { @@ -22,9 +22,9 @@ function preparePlugins(output) { }) // Update book's configuration using the plugins - .then(function(plugins) { + .then((plugins) => { return Plugins.validateConfig(book, plugins) - .then(function(newBook) { + .then((newBook) => { return output.merge({ book: newBook, plugins diff --git a/packages/gitbook/src/output/website/onAsset.js b/packages/gitbook/src/output/website/onAsset.js index b72c47d..b7c1df3 100644 --- a/packages/gitbook/src/output/website/onAsset.js +++ b/packages/gitbook/src/output/website/onAsset.js @@ -17,9 +17,9 @@ function onAsset(output, asset) { const outputPath = path.resolve(outputFolder, asset); return fs.ensureFile(outputPath) - .then(function() { + .then(() => { return bookFS.readAsStream(asset) - .then(function(stream) { + .then((stream) => { return fs.writeStream(outputPath, stream); }); }) diff --git a/packages/gitbook/src/output/website/onPage.js b/packages/gitbook/src/output/website/onPage.js index 90eec63..1d4cd74 100644 --- a/packages/gitbook/src/output/website/onPage.js +++ b/packages/gitbook/src/output/website/onPage.js @@ -19,7 +19,7 @@ function onPage(output, page) { const filePath = urls.resolve(file.getPath()); return Modifiers.modifyHTML(page, getModifiers(output, page)) - .then(function(resultPage) { + .then((resultPage) => { // Generate the context const initialState = JSONUtils.encodeState(output, resultPage); diff --git a/packages/gitbook/src/parse/__tests__/fixtures/glossary/empty.yaml b/packages/gitbook/src/parse/__tests__/fixtures/glossary/empty.yaml new file mode 100644 index 0000000..6291d4b --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/fixtures/glossary/empty.yaml @@ -0,0 +1,6 @@ +nodes: + - kind: block + type: header_one + nodes: + - kind: text + text: Glossary diff --git a/packages/gitbook/src/parse/__tests__/fixtures/glossary/one-entry.yaml b/packages/gitbook/src/parse/__tests__/fixtures/glossary/one-entry.yaml new file mode 100644 index 0000000..8ff5e68 --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/fixtures/glossary/one-entry.yaml @@ -0,0 +1,11 @@ +nodes: + - kind: block + type: header_one + nodes: + - kind: text + text: Glossary + - kind: block + type: header_two + nodes: + - kind: text + text: An entry diff --git a/packages/gitbook/src/parse/__tests__/fixtures/languages/empty.yaml b/packages/gitbook/src/parse/__tests__/fixtures/languages/empty.yaml new file mode 100644 index 0000000..54df26d --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/fixtures/languages/empty.yaml @@ -0,0 +1,6 @@ +nodes: + - kind: block + type: header_one + nodes: + - kind: text + text: Languages diff --git a/packages/gitbook/src/parse/__tests__/fixtures/languages/ul-with-link.yaml b/packages/gitbook/src/parse/__tests__/fixtures/languages/ul-with-link.yaml new file mode 100644 index 0000000..fd5c3c3 --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/fixtures/languages/ul-with-link.yaml @@ -0,0 +1,35 @@ +nodes: + - kind: block + type: header_one + nodes: + - kind: text + text: Languages + - kind: block + type: unordered_list + nodes: + - kind: block + type: list_item + nodes: + - kind: block + type: unstyled + nodes: + - kind: inline + type: link + data: + href: en/ + nodes: + - kind: text + text: English + - kind: block + type: list_item + nodes: + - kind: block + type: unstyled + nodes: + - kind: inline + type: link + data: + href: fr/ + nodes: + - kind: text + text: French diff --git a/packages/gitbook/src/parse/__tests__/fixtures/languages/ul.yaml b/packages/gitbook/src/parse/__tests__/fixtures/languages/ul.yaml new file mode 100644 index 0000000..4c67352 --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/fixtures/languages/ul.yaml @@ -0,0 +1,25 @@ +nodes: + - kind: block + type: header_one + nodes: + - kind: text + text: Languages + - kind: block + type: unordered_list + nodes: + - kind: block + type: list_item + nodes: + - kind: block + type: unstyled + nodes: + - kind: text + text: English + - kind: block + type: list_item + nodes: + - kind: block + type: unstyled + nodes: + - kind: text + text: French diff --git a/packages/gitbook/src/parse/__tests__/fixtures/readme/normal.yaml b/packages/gitbook/src/parse/__tests__/fixtures/readme/normal.yaml new file mode 100644 index 0000000..375b2c3 --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/fixtures/readme/normal.yaml @@ -0,0 +1,11 @@ +nodes: + - kind: block + type: header_one + nodes: + - kind: text + text: Hello World + - kind: block + type: paragraph + nodes: + - kind: text + text: This is a description diff --git a/packages/gitbook/src/parse/__tests__/fixtures/readme/only-title.yaml b/packages/gitbook/src/parse/__tests__/fixtures/readme/only-title.yaml new file mode 100644 index 0000000..1b7c74e --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/fixtures/readme/only-title.yaml @@ -0,0 +1,6 @@ +nodes: + - kind: block + type: header_one + nodes: + - kind: text + text: Hello World diff --git a/packages/gitbook/src/parse/__tests__/fixtures/summary/parts-ul.yaml b/packages/gitbook/src/parse/__tests__/fixtures/summary/parts-ul.yaml new file mode 100644 index 0000000..cf19d33 --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/fixtures/summary/parts-ul.yaml @@ -0,0 +1,33 @@ +nodes: + - kind: block + type: header_one + nodes: + - kind: text + text: Summary + - kind: block + type: unordered_list + nodes: + - kind: block + type: list_item + nodes: + - kind: block + type: unstyled + nodes: + - kind: text + text: Hello + - kind: block + type: header_two + nodes: + - kind: text + text: Some Part + - kind: block + type: unordered_list + nodes: + - kind: block + type: list_item + nodes: + - kind: block + type: unstyled + nodes: + - kind: text + text: World diff --git a/packages/gitbook/src/parse/__tests__/fixtures/summary/ul-with-link.yaml b/packages/gitbook/src/parse/__tests__/fixtures/summary/ul-with-link.yaml new file mode 100644 index 0000000..975fdca --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/fixtures/summary/ul-with-link.yaml @@ -0,0 +1,30 @@ +nodes: + - kind: block + type: header_one + nodes: + - kind: text + text: Summary + - kind: block + type: unordered_list + nodes: + - kind: block + type: list_item + nodes: + - kind: block + type: unstyled + nodes: + - kind: inline + type: link + data: + href: hello.md + nodes: + - kind: text + text: Hello + - kind: block + type: list_item + nodes: + - kind: block + type: unstyled + nodes: + - kind: text + text: World diff --git a/packages/gitbook/src/parse/__tests__/fixtures/summary/ul.yaml b/packages/gitbook/src/parse/__tests__/fixtures/summary/ul.yaml new file mode 100644 index 0000000..3af96c9 --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/fixtures/summary/ul.yaml @@ -0,0 +1,25 @@ +nodes: + - kind: block + type: header_one + nodes: + - kind: text + text: Summary + - kind: block + type: unordered_list + nodes: + - kind: block + type: list_item + nodes: + - kind: block + type: unstyled + nodes: + - kind: text + text: Hello + - kind: block + type: list_item + nodes: + - kind: block + type: unstyled + nodes: + - kind: text + text: World diff --git a/packages/gitbook/src/parse/__tests__/glossaryFromDocument.js b/packages/gitbook/src/parse/__tests__/glossaryFromDocument.js new file mode 100644 index 0000000..d52bcd8 --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/glossaryFromDocument.js @@ -0,0 +1,27 @@ +const expect = require('expect'); +const readDocument = require('./utils/readDocument'); +const glossaryFromDocument = require('../glossaryFromDocument'); + +function readGlossary(filename) { + const document = readDocument(filename); + return glossaryFromDocument(document); +} + +describe('glossaryFromDocument', () => { + + it('should parse empty', () => { + const glossary = readGlossary('glossary/empty.yaml'); + expect(glossary.entries.size).toBe(0); + }); + + it('should parse one entry without description', () => { + const glossary = readGlossary('glossary/one-entry.yaml'); + expect(glossary.entries.size).toBe(1); + + const entry = glossary.entries.first(); + + expect(entry.name).toBe('An entry'); + expect(entry.description).toBe(''); + }); + +}); diff --git a/packages/gitbook/src/parse/__tests__/languagesFromDocument.js b/packages/gitbook/src/parse/__tests__/languagesFromDocument.js new file mode 100644 index 0000000..4e1d4c3 --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/languagesFromDocument.js @@ -0,0 +1,36 @@ +const expect = require('expect'); +const readDocument = require('./utils/readDocument'); +const languagesFromDocument = require('../languagesFromDocument'); + +function readLanguages(filename) { + const document = readDocument(filename); + return languagesFromDocument(document); +} + +describe('languagesFromDocument', () => { + + it('should parse empty', () => { + const languages = readLanguages('languages/empty.yaml'); + expect(languages.getCount()).toBe(0); + }); + + it('should parse ul list', () => { + const languages = readLanguages('languages/ul.yaml'); + expect(languages.getCount()).toBe(0); + }); + + it('should parse ul list with links', () => { + const languages = readLanguages('languages/ul-with-link.yaml'); + expect(languages.getCount()).toBe(2); + + const first = languages.list.first(); + const second = languages.list.last(); + + expect(first.title).toBe('English'); + expect(first.path).toBe('en/'); + + expect(second.title).toBe('French'); + expect(second.path).toBe('fr/'); + }); + +}); diff --git a/packages/gitbook/src/parse/__tests__/listAssets.js b/packages/gitbook/src/parse/__tests__/listAssets.js index 102aed9..34bccf0 100644 --- a/packages/gitbook/src/parse/__tests__/listAssets.js +++ b/packages/gitbook/src/parse/__tests__/listAssets.js @@ -5,8 +5,8 @@ const createMockFS = require('../../fs/mock'); const listAssets = require('../listAssets'); const parseGlossary = require('../parseGlossary'); -describe('listAssets', function() { - it('should not list glossary as asset', function() { +describe('listAssets', () => { + it('should not list glossary as asset', () => { const fs = createMockFS({ 'GLOSSARY.md': '# Glossary\n\n## Hello\nDescription for hello', 'assetFile.js': '', @@ -17,10 +17,10 @@ describe('listAssets', function() { const book = Book.createForFS(fs); return parseGlossary(book) - .then(function(resultBook) { + .then((resultBook) => { return listAssets(resultBook, Immutable.Map()); }) - .then(function(assets) { + .then((assets) => { expect(assets.size).toBe(2); expect(assets.includes('assetFile.js')); expect(assets.includes('assets/file.js')); diff --git a/packages/gitbook/src/parse/__tests__/parseBook.js b/packages/gitbook/src/parse/__tests__/parseBook.js index d5de25c..f6f30d3 100644 --- a/packages/gitbook/src/parse/__tests__/parseBook.js +++ b/packages/gitbook/src/parse/__tests__/parseBook.js @@ -1,10 +1,10 @@ const Book = require('../../models/book'); const createMockFS = require('../../fs/mock'); -describe('parseBook', function() { +describe('parseBook', () => { const parseBook = require('../parseBook'); - it('should parse multilingual book', function() { + it('should parse multilingual book', () => { const fs = createMockFS({ 'LANGS.md': '# Languages\n\n* [en](en)\n* [fr](fr)', 'en': { @@ -17,7 +17,7 @@ describe('parseBook', function() { const book = Book.createForFS(fs); return parseBook(book) - .then(function(resultBook) { + .then((resultBook) => { const languages = resultBook.getLanguages(); const books = resultBook.getBooks(); @@ -27,7 +27,7 @@ describe('parseBook', function() { }); }); - it('should extend configuration for multilingual book', function() { + it('should extend configuration for multilingual book', () => { const fs = createMockFS({ 'LANGS.md': '# Languages\n\n* [en](en)\n* [fr](fr)', 'book.json': '{ "title": "Test", "author": "GitBook" }', @@ -42,7 +42,7 @@ describe('parseBook', function() { const book = Book.createForFS(fs); return parseBook(book) - .then(function(resultBook) { + .then((resultBook) => { const books = resultBook.getBooks(); expect(resultBook.isMultilingual()).toBe(true); @@ -62,7 +62,7 @@ describe('parseBook', function() { }); }); - it('should parse book in a directory', function() { + it('should parse book in a directory', () => { const fs = createMockFS({ 'book.json': JSON.stringify({ root: './test' @@ -76,7 +76,7 @@ describe('parseBook', function() { const book = Book.createForFS(fs); return parseBook(book) - .then(function(resultBook) { + .then((resultBook) => { const readme = resultBook.getReadme(); const summary = resultBook.getSummary(); const articles = summary.getArticlesAsList(); diff --git a/packages/gitbook/src/parse/__tests__/parseGlossary.js b/packages/gitbook/src/parse/__tests__/parseGlossary.js index ba2e407..d96dc1b 100644 --- a/packages/gitbook/src/parse/__tests__/parseGlossary.js +++ b/packages/gitbook/src/parse/__tests__/parseGlossary.js @@ -1,17 +1,17 @@ const Book = require('../../models/book'); const createMockFS = require('../../fs/mock'); -describe('parseGlossary', function() { +describe('parseGlossary', () => { const parseGlossary = require('../parseGlossary'); - it('should parse glossary if exists', function() { + it('should parse glossary if exists', () => { const fs = createMockFS({ 'GLOSSARY.md': '# Glossary\n\n## Hello\nDescription for hello' }); const book = Book.createForFS(fs); return parseGlossary(book) - .then(function(resultBook) { + .then((resultBook) => { const glossary = resultBook.getGlossary(); const file = glossary.getFile(); const entries = glossary.getEntries(); @@ -21,12 +21,12 @@ describe('parseGlossary', function() { }); }); - it('should not fail if doesn\'t exist', function() { + it('should not fail if doesn\'t exist', () => { const fs = createMockFS({}); const book = Book.createForFS(fs); return parseGlossary(book) - .then(function(resultBook) { + .then((resultBook) => { const glossary = resultBook.getGlossary(); const file = glossary.getFile(); diff --git a/packages/gitbook/src/parse/__tests__/parseIgnore.js b/packages/gitbook/src/parse/__tests__/parseIgnore.js index b1bd43c..fa4ea33 100644 --- a/packages/gitbook/src/parse/__tests__/parseIgnore.js +++ b/packages/gitbook/src/parse/__tests__/parseIgnore.js @@ -1,7 +1,7 @@ const Book = require('../../models/book'); const createMockFS = require('../../fs/mock'); -describe('parseIgnore', function() { +describe('parseIgnore', () => { const parseIgnore = require('../parseIgnore'); const fs = createMockFS({ '.ignore': 'test-1.js', @@ -17,23 +17,23 @@ describe('parseIgnore', function() { return parseIgnore(book); } - it('should load rules from .ignore', function() { + it('should load rules from .ignore', () => { return getBook() - .then(function(book) { + .then((book) => { expect(book.isFileIgnored('test-1.js')).toBeTruthy(); }); }); - it('should load rules from .gitignore', function() { + it('should load rules from .gitignore', () => { return getBook() - .then(function(book) { + .then((book) => { expect(book.isFileIgnored('test-2.js')).toBeTruthy(); }); }); - it('should load rules from .bookignore', function() { + it('should load rules from .bookignore', () => { return getBook() - .then(function(book) { + .then((book) => { expect(book.isFileIgnored('test-3.js')).toBeFalsy(); }); }); diff --git a/packages/gitbook/src/parse/__tests__/parsePageFromString.js b/packages/gitbook/src/parse/__tests__/parsePageFromString.js index 13bc544..3357f29 100644 --- a/packages/gitbook/src/parse/__tests__/parsePageFromString.js +++ b/packages/gitbook/src/parse/__tests__/parsePageFromString.js @@ -1,10 +1,10 @@ const parsePageFromString = require('../parsePageFromString'); const Page = require('../../models/page'); -describe('parsePageFromString', function() { +describe('parsePageFromString', () => { const page = new Page(); - it('should parse YAML frontmatter', function() { + it('should parse YAML frontmatter', () => { const CONTENT = '---\nhello: true\nworld: "cool"\n---\n# Hello World\n'; const newPage = parsePageFromString(page, CONTENT); @@ -17,7 +17,7 @@ describe('parsePageFromString', function() { expect(attrs.get('world')).toBe('cool'); }); - it('should parse text direction (english)', function() { + it('should parse text direction (english)', () => { const CONTENT = 'Hello World'; const newPage = parsePageFromString(page, CONTENT); @@ -26,7 +26,7 @@ describe('parsePageFromString', function() { expect(newPage.getAttributes().size).toBe(0); }); - it('should parse text direction (arab)', function() { + it('should parse text direction (arab)', () => { const CONTENT = 'Ù…Ø±ØØ¨Ø§ بالعالم'; const newPage = parsePageFromString(page, CONTENT); diff --git a/packages/gitbook/src/parse/__tests__/parseReadme.js b/packages/gitbook/src/parse/__tests__/parseReadme.js index 45ecfa3..77207a2 100644 --- a/packages/gitbook/src/parse/__tests__/parseReadme.js +++ b/packages/gitbook/src/parse/__tests__/parseReadme.js @@ -1,35 +1,34 @@ const Promise = require('../../utils/promise'); const Book = require('../../models/book'); const createMockFS = require('../../fs/mock'); +const parseReadme = require('../parseReadme'); -describe('parseReadme', function() { - const parseReadme = require('../parseReadme'); - - it('should parse summary if exists', function() { +describe('parseReadme', () => { + it('should parse readme if exists', () => { const fs = createMockFS({ 'README.md': '# Hello\n\nAnd here is the description.' }); const book = Book.createForFS(fs); return parseReadme(book) - .then(function(resultBook) { + .then((resultBook) => { const readme = resultBook.getReadme(); const file = readme.getFile(); expect(file.exists()).toBeTruthy(); - expect(readme.getTitle()).toBe('Hello'); - expect(readme.getDescription()).toBe('And here is the description.'); + expect(readme.title).toBe('Hello'); + expect(readme.description).toBe('And here is the description.'); }); }); - it('should fail if doesn\'t exist', function() { + it('should fail if doesn\'t exist', () => { const fs = createMockFS({}); const book = Book.createForFS(fs); return parseReadme(book) - .then(function(resultBook) { + .then((resultBook) => { throw new Error('It should have fail'); - }, function() { + }, () => { return Promise(); }); }); diff --git a/packages/gitbook/src/parse/__tests__/parseSummary.js b/packages/gitbook/src/parse/__tests__/parseSummary.js index 8b86c45..5cc7366 100644 --- a/packages/gitbook/src/parse/__tests__/parseSummary.js +++ b/packages/gitbook/src/parse/__tests__/parseSummary.js @@ -1,17 +1,16 @@ const Book = require('../../models/book'); const createMockFS = require('../../fs/mock'); +const parseSummary = require('../parseSummary'); -describe('parseSummary', function() { - const parseSummary = require('../parseSummary'); - - it('should parse summary if exists', function() { +describe('parseSummary', () => { + it('should parse summary if exists', () => { const fs = createMockFS({ 'SUMMARY.md': '# Summary\n\n* [Hello](hello.md)' }); const book = Book.createForFS(fs); return parseSummary(book) - .then(function(resultBook) { + .then((resultBook) => { const summary = resultBook.getSummary(); const file = summary.getFile(); @@ -19,12 +18,12 @@ describe('parseSummary', function() { }); }); - it('should not fail if doesn\'t exist', function() { + it('should not fail if doesn\'t exist', () => { const fs = createMockFS({}); const book = Book.createForFS(fs); return parseSummary(book) - .then(function(resultBook) { + .then((resultBook) => { const summary = resultBook.getSummary(); const file = summary.getFile(); diff --git a/packages/gitbook/src/parse/__tests__/readmeFromDocument.js b/packages/gitbook/src/parse/__tests__/readmeFromDocument.js new file mode 100644 index 0000000..6027fe5 --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/readmeFromDocument.js @@ -0,0 +1,24 @@ +const expect = require('expect'); +const readDocument = require('./utils/readDocument'); +const readmeFromDocument = require('../readmeFromDocument'); + +function readReadme(filename) { + const document = readDocument(filename); + return readmeFromDocument(document); +} + +describe('readmeFromDocument', () => { + + it('should parse only title', () => { + const readme = readReadme('readme/only-title.yaml'); + expect(readme.title).toBe('Hello World'); + expect(readme.description).toBe(''); + }); + + it('should parse title and description', () => { + const readme = readReadme('readme/normal.yaml'); + expect(readme.title).toBe('Hello World'); + expect(readme.description).toBe('This is a description'); + }); + +}); diff --git a/packages/gitbook/src/parse/__tests__/summaryFromDocument.js b/packages/gitbook/src/parse/__tests__/summaryFromDocument.js new file mode 100644 index 0000000..7c9436e --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/summaryFromDocument.js @@ -0,0 +1,47 @@ +const expect = require('expect'); +const readDocument = require('./utils/readDocument'); +const summaryFromDocument = require('../summaryFromDocument'); + +function readSummary(filename) { + const document = readDocument(filename); + return summaryFromDocument(document); +} + +describe('summaryFromDocument', () => { + + it('should parse from a UL', () => { + const summary = readSummary('summary/ul.yaml'); + expect(summary.parts.size).toBe(1); + + const first = summary.getByLevel('1.1'); + expect(first).toExist(); + expect(first.title).toBe('Hello'); + + const last = summary.getByLevel('1.2'); + expect(last).toExist(); + expect(last.title).toBe('World'); + }); + + it('should parse from a UL with links', () => { + const summary = readSummary('summary/ul-with-link.yaml'); + const first = summary.getByLevel('1.1'); + + expect(first).toExist(); + expect(first.title).toBe('Hello'); + expect(first.ref).toBe('hello.md'); + }); + + it('should parse multiple parts', () => { + const summary = readSummary('summary/parts-ul.yaml'); + expect(summary.parts.size).toBe(2); + + const first = summary.getByLevel('1.1'); + expect(first).toExist(); + expect(first.title).toBe('Hello'); + + const last = summary.getByLevel('2.1'); + expect(last).toExist(); + expect(last.title).toBe('World'); + }); + +}); diff --git a/packages/gitbook/src/parse/__tests__/utils/readDocument.js b/packages/gitbook/src/parse/__tests__/utils/readDocument.js new file mode 100644 index 0000000..ab5bcb5 --- /dev/null +++ b/packages/gitbook/src/parse/__tests__/utils/readDocument.js @@ -0,0 +1,21 @@ +const path = require('path'); +const read = require('read-metadata'); +const { Raw } = require('slate'); + +const FIXTURES = path.resolve(__dirname, '../fixtures'); + +/** + * Read a fixture document from a YAML file. + * @param {String} filename + * @return {Document} + */ +function readDocument(filename) { + filename = path.resolve(FIXTURES, filename); + + const yaml = read.sync(filename); + const { document } = Raw.deserializeState(yaml, { terse: true }); + + return document; +} + +module.exports = readDocument; diff --git a/packages/gitbook/src/parse/findParsableFile.js b/packages/gitbook/src/parse/findParsableFile.js index c30dbbd..3c72c57 100644 --- a/packages/gitbook/src/parse/findParsableFile.js +++ b/packages/gitbook/src/parse/findParsableFile.js @@ -1,29 +1,25 @@ const path = require('path'); const Promise = require('../utils/promise'); -const parsers = require('../parsers'); +const { FILE_EXTENSIONS } = require('../parsers'); /** - Find a file parsable (Markdown or AsciiDoc) in a book - - @param {Book} book - @param {String} filename - @return {Promise<File | Undefined>} -*/ + * Find a file parsable (Markdown or AsciiDoc) in a book + * + * @param {Book} book + * @param {String} filename + * @return {Promise<File | Undefined>} + */ function findParsableFile(book, filename) { const fs = book.getContentFS(); - const ext = path.extname(filename); - const basename = path.basename(filename, ext); + const basename = path.basename(filename, path.extname(filename)); const basedir = path.dirname(filename); - // Ordered list of extensions to test - const exts = parsers.extensions; - - return Promise.some(exts, function(ext) { + return Promise.some(FILE_EXTENSIONS, (ext) => { const filepath = basename + ext; return fs.findFile(basedir, filepath) - .then(function(found) { + .then((found) => { if (!found || book.isContentFileIgnored(found)) { return undefined; } diff --git a/packages/gitbook/src/parse/glossaryFromDocument.js b/packages/gitbook/src/parse/glossaryFromDocument.js new file mode 100644 index 0000000..4b5bf3d --- /dev/null +++ b/packages/gitbook/src/parse/glossaryFromDocument.js @@ -0,0 +1,42 @@ +const { BLOCKS } = require('markup-it'); +const Glossary = require('../models/glossary'); + +/** + * Return true if a node is a entry title. + * @param {Node} node + * @return {Boolean} + */ +const isTitle = node => node.type == BLOCKS.HEADING_2; + +/** + * Return true if a node is a entry description. + * @param {Node} node + * @return {Boolean} + */ +const isDescription = node => node.type !== BLOCKS.HEADING_2 && node.type !== BLOCKS.CODE; + +/** + * Parse a readme from a document. + * @param {Document} document + * @return {Readme} readme + */ +function glossaryFromDocument(document) { + const { nodes } = document; + const entries = []; + + nodes.forEach((block, i) => { + const next = nodes.get(i); + + if (isTitle(block)) { + entries.push({ + name: block.text, + description: (next && isDescription(next)) ? next.text : '' + }); + } + }); + + + return Glossary.createFromEntries(entries); +} + +module.exports = glossaryFromDocument; diff --git a/packages/gitbook/src/parse/languagesFromDocument.js b/packages/gitbook/src/parse/languagesFromDocument.js new file mode 100644 index 0000000..c163156 --- /dev/null +++ b/packages/gitbook/src/parse/languagesFromDocument.js @@ -0,0 +1,30 @@ +const { BLOCKS } = require('markup-it'); +const Languages = require('../models/languages'); +const { listArticles } = require('./summaryFromDocument'); + +const isList = node => node.type === BLOCKS.OL_LIST || node.type === BLOCKS.UL_LIST; + +/** + * Parse a languages listing from a document. + * @param {Document} document + * @return {Languages} languages + */ +function languagesFromDocument(document) { + const { nodes } = document; + + const list = nodes.find(isList); + + if (!list) { + return new Languages(); + } + + const articles = listArticles(list); + + return Languages.createFromList( + articles + .filter(article => article.ref) + .map(article => ({ title: article.title, path: article.ref })) + ); +} + +module.exports = languagesFromDocument; diff --git a/packages/gitbook/src/parse/lookupStructureFile.js b/packages/gitbook/src/parse/lookupStructureFile.js index e54a769..17af9a1 100644 --- a/packages/gitbook/src/parse/lookupStructureFile.js +++ b/packages/gitbook/src/parse/lookupStructureFile.js @@ -1,17 +1,16 @@ const findParsableFile = require('./findParsableFile'); /** - Lookup a structure file (ex: SUMMARY.md, GLOSSARY.md) in a book. Uses - book's config to find it. - - @param {Book} book - @param {String} type: one of ["glossary", "readme", "summary", "langs"] - @return {Promise<File | Undefined>} The path of the file found, relative - to the book content root. -*/ + * Lookup a structure file (ex: SUMMARY.md, GLOSSARY.md) in a book. Uses + * book's config to find it. + * + * @param {Book} book + * @param {String} type: one of ["glossary", "readme", "summary", "langs"] + * @return {Promise<File | Undefined>} The path of the file found, relative + * to the book content root. + */ function lookupStructureFile(book, type) { - const config = book.getConfig(); - + const { config } = book; const fileToSearch = config.getValue(['structure', type]); return findParsableFile(book, fileToSearch); diff --git a/packages/gitbook/src/parse/parseBook.js b/packages/gitbook/src/parse/parseBook.js index e5c1784..1ce76dd 100644 --- a/packages/gitbook/src/parse/parseBook.js +++ b/packages/gitbook/src/parse/parseBook.js @@ -32,7 +32,7 @@ function parseMultilingualBook(book) { const languages = book.getLanguages(); const langList = languages.getList(); - return Promise.reduce(langList, function(currentBook, lang) { + return Promise.reduce(langList, (currentBook, lang) => { const langID = lang.getID(); const child = Book.createFromParent(currentBook, langID); let ignore = currentBook.getIgnore(); @@ -40,7 +40,7 @@ function parseMultilingualBook(book) { return Promise(child) .then(parseConfig) .then(parseBookContent) - .then(function(result) { + .then((result) => { // Ignore content of this book when generating parent book ignore = ignore.add(langID + '/**'); currentBook = currentBook.set('ignore', ignore); @@ -64,7 +64,7 @@ function parseBook(book) { .then(parseIgnore) .then(parseConfig) .then(parseLanguages) - .then(function(resultBook) { + .then((resultBook) => { if (resultBook.isMultilingual()) { return parseMultilingualBook(resultBook); } else { diff --git a/packages/gitbook/src/parse/parseConfig.js b/packages/gitbook/src/parse/parseConfig.js index cd27426..81aa757 100644 --- a/packages/gitbook/src/parse/parseConfig.js +++ b/packages/gitbook/src/parse/parseConfig.js @@ -13,7 +13,7 @@ function parseConfig(book) { const fs = book.getFS(); let config = book.getConfig(); - return Promise.some(CONFIG_FILES, function(filename) { + return Promise.some(CONFIG_FILES, (filename) => { // Is this file ignored? if (book.isFileIgnored(filename)) { return; @@ -21,22 +21,22 @@ function parseConfig(book) { // Try loading it return fs.loadAsObject(filename) - .then(function(cfg) { + .then((cfg) => { return fs.statFile(filename) - .then(function(file) { + .then((file) => { return { file, values: cfg }; }); }) - .fail(function(err) { + .fail((err) => { if (err.code != 'MODULE_NOT_FOUND') throw (err); else return Promise(false); }); }) - .then(function(result) { + .then((result) => { let values = result ? result.values : {}; values = validateConfig(values); diff --git a/packages/gitbook/src/parse/parseGlossary.js b/packages/gitbook/src/parse/parseGlossary.js index 052985b..afd3765 100644 --- a/packages/gitbook/src/parse/parseGlossary.js +++ b/packages/gitbook/src/parse/parseGlossary.js @@ -1,25 +1,30 @@ -const parseStructureFile = require('./parseStructureFile'); -const Glossary = require('../models/glossary'); +const lookupStructureFile = require('./lookupStructureFile'); +const glossaryFromDocument = require('./glossaryFromDocument'); /** - Parse glossary - - @param {Book} book - @return {Promise<Book>} -*/ + * Parse glossary. + * + * @param {Book} book + * @return {Promise<Book>} + */ function parseGlossary(book) { - const logger = book.getLogger(); + const { logger } = book; + const fs = book.getContentFS(); - return parseStructureFile(book, 'glossary') - .spread(function(file, entries) { + return lookupStructureFile(book, 'glossary') + .then((file) => { if (!file) { + logger.debug.ln('no glossary located'); return book; } - logger.debug.ln('glossary index file found at', file.getPath()); - - const glossary = Glossary.createFromEntries(file, entries); - return book.set('glossary', glossary); + logger.debug.ln(`glossary found at ${file.path}`); + return file.parse(fs) + .then((document) => { + let glossary = glossaryFromDocument(document); + glossary = glossary.setFile(file); + return book.set('glossary', glossary); + }); }); } diff --git a/packages/gitbook/src/parse/parseLanguages.js b/packages/gitbook/src/parse/parseLanguages.js index 1b28930..1fc3061 100644 --- a/packages/gitbook/src/parse/parseLanguages.js +++ b/packages/gitbook/src/parse/parseLanguages.js @@ -1,27 +1,33 @@ -const parseStructureFile = require('./parseStructureFile'); -const Languages = require('../models/languages'); +const lookupStructureFile = require('./lookupStructureFile'); +const languagesFromDocument = require('./languagesFromDocument'); /** - Parse languages list from book - - @param {Book} book - @return {Promise<Book>} -*/ + * Parse languages list from book + * + * @param {Book} book + * @return {Promise<Book>} + */ function parseLanguages(book) { - const logger = book.getLogger(); + const { logger } = book; + const fs = book.getContentFS(); - return parseStructureFile(book, 'langs') - .spread(function(file, result) { + return lookupStructureFile(book, 'langs') + .then((file) => { if (!file) { return book; } - const languages = Languages.createFromList(file, result); + logger.debug.ln(`languages index found at ${file.path}`); + + return file.parse(fs) + .then((document) => { + let languages = languagesFromDocument(document); + languages = languages.merge({ file }); - logger.debug.ln('languages index file found at', file.getPath()); - logger.info.ln('parsing multilingual book, with', languages.getList().size, 'languages'); + logger.info.ln(`parsing multilingual book, with ${languages.list.size} languages`); - return book.set('languages', languages); + return book.set('languages', languages); + }); }); } diff --git a/packages/gitbook/src/parse/parsePage.js b/packages/gitbook/src/parse/parsePage.js index 72f9ddf..a530392 100644 --- a/packages/gitbook/src/parse/parsePage.js +++ b/packages/gitbook/src/parse/parsePage.js @@ -12,7 +12,7 @@ function parsePage(book, page) { const file = page.getFile(); return fs.readAsString(file.getPath()) - .then(function(content) { + .then((content) => { return parsePageFromString(page, content); }); } diff --git a/packages/gitbook/src/parse/parsePagesList.js b/packages/gitbook/src/parse/parsePagesList.js index 89a1a4f..a6b9d51 100644 --- a/packages/gitbook/src/parse/parsePagesList.js +++ b/packages/gitbook/src/parse/parsePagesList.js @@ -1,4 +1,4 @@ -const Immutable = require('immutable'); +const { OrderedMap } = require('immutable'); const timing = require('../utils/timing'); const Page = require('../models/page'); @@ -18,16 +18,16 @@ function parseFilePage(book, filePath) { return fs.statFile(filePath) .then( - function(file) { + (file) => { const page = Page.createForFile(file); return parsePage(book, page); }, - function(err) { + (err) => { // file doesn't exist return null; } ) - .fail(function(err) { + .fail((err) => { const logger = book.getLogger(); logger.error.ln('error while parsing page "' + filePath + '":'); throw err; @@ -44,12 +44,12 @@ function parseFilePage(book, filePath) { function parsePagesList(book) { const summary = book.getSummary(); const glossary = book.getGlossary(); - let map = Immutable.OrderedMap(); + let map = OrderedMap(); // Parse pages from summary return timing.measure( 'parse.listPages', - walkSummary(summary, function(article) { + walkSummary(summary, (article) => { if (!article.isPage()) return; const filepath = article.getPath(); @@ -58,7 +58,7 @@ function parsePagesList(book) { if (book.isContentFileIgnored(filepath)) return; return parseFilePage(book, filepath) - .then(function(page) { + .then((page) => { // file doesn't exist if (!page) { return; @@ -70,7 +70,7 @@ function parsePagesList(book) { ) // Parse glossary - .then(function() { + .then(() => { const file = glossary.getFile(); if (!file.exists()) { @@ -78,7 +78,7 @@ function parsePagesList(book) { } return parseFilePage(book, file.getPath()) - .then(function(page) { + .then((page) => { // file doesn't exist if (!page) { return; @@ -88,7 +88,7 @@ function parsePagesList(book) { }); }) - .then(function() { + .then(() => { return map; }); } diff --git a/packages/gitbook/src/parse/parseReadme.js b/packages/gitbook/src/parse/parseReadme.js index 82f8f19..ce5cd82 100644 --- a/packages/gitbook/src/parse/parseReadme.js +++ b/packages/gitbook/src/parse/parseReadme.js @@ -1,27 +1,30 @@ -const parseStructureFile = require('./parseStructureFile'); -const Readme = require('../models/readme'); - +const lookupStructureFile = require('./lookupStructureFile'); +const readmeFromDocument = require('./readmeFromDocument'); const error = require('../utils/error'); /** - Parse readme from book - - @param {Book} book - @return {Promise<Book>} -*/ + * Parse readme from book. + * + * @param {Book} book + * @return {Promise<Book>} + */ function parseReadme(book) { - const logger = book.getLogger(); + const { logger } = book; + const fs = book.getContentFS(); - return parseStructureFile(book, 'readme') - .spread(function(file, result) { + return lookupStructureFile(book, 'readme') + .then((file) => { if (!file) { throw new error.FileNotFoundError({ filename: 'README' }); } - logger.debug.ln('readme found at', file.getPath()); - - const readme = Readme.create(file, result); - return book.set('readme', readme); + logger.debug.ln(`readme found at ${file.path}`); + return file.parse(fs) + .then((document) => { + let readme = readmeFromDocument(document); + readme = readme.setFile(file); + return book.set('readme', readme); + }); }); } diff --git a/packages/gitbook/src/parse/parseStructureFile.js b/packages/gitbook/src/parse/parseStructureFile.js deleted file mode 100644 index 951da96..0000000 --- a/packages/gitbook/src/parse/parseStructureFile.js +++ /dev/null @@ -1,67 +0,0 @@ -const Promise = require('../utils/promise'); -const error = require('../utils/error'); -const lookupStructureFile = require('./lookupStructureFile'); - -/** - Parse a ParsableFile using a specific method - - @param {FS} fs - @param {ParsableFile} file - @param {String} type - @return {Promise<Array<String, List|Map>>} -*/ -function parseFile(fs, file, type) { - const filepath = file.getPath(); - const parser = file.getParser(); - - if (!parser) { - return Promise.reject( - error.FileNotParsableError({ - filename: filepath - }) - ); - } - - return fs.readAsString(filepath) - .then(function(content) { - if (type === 'readme') { - return parser.parseReadme(content); - } else if (type === 'glossary') { - return parser.parseGlossary(content); - } else if (type === 'summary') { - return parser.parseSummary(content); - } else if (type === 'langs') { - return parser.parseLanguages(content); - } else { - throw new Error('Parsing invalid type "' + type + '"'); - } - }) - .then(function(result) { - return [ - file, - result - ]; - }); -} - - -/** - Parse a structure file (ex: SUMMARY.md, GLOSSARY.md). - It uses the configuration to find the specified file. - - @param {Book} book - @param {String} type: one of ["glossary", "readme", "summary"] - @return {Promise<List|Map>} -*/ -function parseStructureFile(book, type) { - const fs = book.getContentFS(); - - return lookupStructureFile(book, type) - .then(function(file) { - if (!file) return [undefined, undefined]; - - return parseFile(fs, file, type); - }); -} - -module.exports = parseStructureFile; diff --git a/packages/gitbook/src/parse/parseSummary.js b/packages/gitbook/src/parse/parseSummary.js index 9488341..022bbfe 100644 --- a/packages/gitbook/src/parse/parseSummary.js +++ b/packages/gitbook/src/parse/parseSummary.js @@ -1,38 +1,54 @@ -const parseStructureFile = require('./parseStructureFile'); const Summary = require('../models/summary'); +const lookupStructureFile = require('./lookupStructureFile'); +const summaryFromDocument = require('./summaryFromDocument'); const SummaryModifier = require('../modifiers').Summary; /** - Parse summary in a book, the summary can only be parsed - if the readme as be detected before. + * Read the summary from a file. + * @param {Book} book + * @param {File} file + * @return {Promise<Summary>} summary + */ +function readSummary(book, file) { + const fs = book.getContentFS(); + + return file.parse(fs) + .then((document) => { + const summary = summaryFromDocument(document); + return summary.setFile(file); + }); +} - @param {Book} book - @return {Promise<Book>} -*/ +/** + * Parse summary in a book, the summary can only be parsed + * if the readme as be detected before. + * + * @param {Book} book + * @return {Promise<Book>} + */ function parseSummary(book) { - const readme = book.getReadme(); - const logger = book.getLogger(); - const readmeFile = readme.getFile(); - - return parseStructureFile(book, 'summary') - .spread(function(file, result) { - let summary; + const { readme, logger } = book; + return lookupStructureFile(book, 'summary') + .then((file) => { if (!file) { logger.warn.ln('no summary file in this book'); - summary = Summary(); + return new Summary(); } else { - logger.debug.ln('summary file found at', file.getPath()); - summary = Summary.createFromParts(file, result.parts); + logger.debug.ln('summary file found at', file.path); + return readSummary(book, file); } + }) - // Insert readme as first entry if not in SUMMARY.md - const readmeArticle = summary.getByPath(readmeFile.getPath()); + // Insert readme as first entry if not in SUMMARY.md + .then((summary) => { + const readmeFile = readme.getFile(); + const readmeArticle = summary.getByPath(readmeFile.path); if (readmeFile.exists() && !readmeArticle) { summary = SummaryModifier.unshiftArticle(summary, { title: 'Introduction', - ref: readmeFile.getPath() + ref: readmeFile.path }); } diff --git a/packages/gitbook/src/parse/readmeFromDocument.js b/packages/gitbook/src/parse/readmeFromDocument.js new file mode 100644 index 0000000..a1f67b8 --- /dev/null +++ b/packages/gitbook/src/parse/readmeFromDocument.js @@ -0,0 +1,21 @@ +const { BLOCKS } = require('markup-it'); +const Readme = require('../models/readme'); + +/** + * Parse a readme from a document. + * @param {Document} document + * @return {Readme} readme + */ +function readmeFromDocument(document) { + const { nodes } = document; + + const first = nodes.first(); + const second = nodes.get(1); + + return Readme.create({ + title: first && first.type == BLOCKS.HEADING_1 ? first.text : '', + description: second && second.type == BLOCKS.PARAGRAPH ? second.text : '' + }); +} + +module.exports = readmeFromDocument; diff --git a/packages/gitbook/src/parse/summaryFromDocument.js b/packages/gitbook/src/parse/summaryFromDocument.js new file mode 100644 index 0000000..8b35897 --- /dev/null +++ b/packages/gitbook/src/parse/summaryFromDocument.js @@ -0,0 +1,87 @@ +const Summary = require('../models/summary'); + +const { BLOCKS, INLINES } = require('markup-it'); +const { List } = require('immutable'); + +const isList = node => node.type === BLOCKS.OL_LIST || node.type === BLOCKS.UL_LIST; +const isLink = node => node.type === INLINES.LINK; + +/** + * Create a summary article from a list item. + * @param {Block} item + * @return {SummaryArticleLike} article + */ +function createArticleFromItem(item) { + const { nodes } = item; + + const titleParent = nodes.first(); + const list = nodes.skip(1).find(isList); + const articles = list ? listArticles(list) : []; + const title = titleParent.text; + const link = titleParent.findDescendant(isLink); + const ref = link ? link.data.get('href') : null; + + return { + title, + ref, + articles + }; +} + +/** + * List articles in a list node. + * @param {Block} list + * @return {List<SummaryArticleLike>} articles + */ +function listArticles(list) { + const { nodes } = list; + return nodes.map(item => createArticleFromItem(item)); +} + +/** + * List summary parts in a document. + * @param {Document} document + * @return {List<SummaryPart>} parts + */ +function listParts(document) { + const { nodes } = document; + const parts = []; + let title = ''; + + nodes.forEach((node) => { + const isHeading = ( + node.type == BLOCKS.HEADING_2 || + node.type == BLOCKS.HEADING_3 + ); + + if (isHeading) { + title = node.text; + } + + if (isList(node)) { + const articles = listArticles(node); + parts.push({ + title, + articles + }); + + title = ''; + } + }); + + return List(parts); +} + +/** + * Parse a summary from a document. + * @param {Document} document + * @return {Summary} summary + */ +function summaryFromDocument(document) { + const parts = listParts(document); + return Summary.createFromParts(parts); +} + +module.exports = summaryFromDocument; +module.exports.listArticles = listArticles; +module.exports.createArticleFromItem = createArticleFromItem; diff --git a/packages/gitbook/src/parse/validateConfig.js b/packages/gitbook/src/parse/validateConfig.js index e766fae..55196f9 100644 --- a/packages/gitbook/src/parse/validateConfig.js +++ b/packages/gitbook/src/parse/validateConfig.js @@ -6,12 +6,12 @@ const error = require('../utils/error'); const mergeDefaults = require('../utils/mergeDefaults'); /** - Validate a book.json content - And return a mix with the default value - - @param {Object} bookJson - @return {Object} -*/ + * Validate a book.json content + * And return a mix with the default value + * + * @param {Object} bookJson + * @return {Object} + */ function validateConfig(bookJson) { const v = new jsonschema.Validator(); const result = v.validate(bookJson, schema, { diff --git a/packages/gitbook/src/parse/walkSummary.js b/packages/gitbook/src/parse/walkSummary.js index 47feb1f..046965b 100644 --- a/packages/gitbook/src/parse/walkSummary.js +++ b/packages/gitbook/src/parse/walkSummary.js @@ -8,9 +8,9 @@ const Promise = require('../utils/promise'); @return {Promise} */ function walkArticles(articles, fn) { - return Promise.forEach(articles, function(article) { + return Promise.forEach(articles, (article) => { return Promise(fn(article)) - .then(function() { + .then(() => { return walkArticles(article.getArticles(), fn); }); }); @@ -26,7 +26,7 @@ function walkArticles(articles, fn) { function walkSummary(summary, fn) { const parts = summary.getParts(); - return Promise.forEach(parts, function(part) { + return Promise.forEach(parts, (part) => { return walkArticles(part.getArticles(), fn); }); } diff --git a/packages/gitbook/src/parsers.js b/packages/gitbook/src/parsers.js deleted file mode 100644 index 62c3776..0000000 --- a/packages/gitbook/src/parsers.js +++ /dev/null @@ -1,63 +0,0 @@ -const path = require('path'); -const Immutable = require('immutable'); - -const markdownParser = require('gitbook-markdown'); -const asciidocParser = require('gitbook-asciidoc'); - -const EXTENSIONS_MARKDOWN = require('./constants/extsMarkdown'); -const EXTENSIONS_ASCIIDOC = require('./constants/extsAsciidoc'); -const Parser = require('./models/parser'); - -// This list is ordered by priority of parsers to use -const parsers = Immutable.List([ - Parser.create('markdown', EXTENSIONS_MARKDOWN, markdownParser), - Parser.create('asciidoc', EXTENSIONS_ASCIIDOC, asciidocParser) -]); - -/** - * Return a specific parser by its name - * - * @param {String} name - * @return {Parser|undefined} - */ -function getParser(name) { - return parsers.find(function(parser) { - return parser.getName() === name; - }); -} - -/** - * Return a specific parser according to an extension - * - * @param {String} ext - * @return {Parser|undefined} - */ -function getParserByExt(ext) { - return parsers.find(function(parser) { - return parser.matchExtension(ext); - }); -} - -/** - * Return parser for a file - * - * @param {String} ext - * @return {Parser|undefined} - */ -function getParserForFile(filename) { - return getParserByExt(path.extname(filename)); -} - -// List all parsable extensions -const extensions = parsers - .map(function(parser) { - return parser.getExtensions(); - }) - .flatten(); - -module.exports = { - extensions, - get: getParser, - getByExt: getParserByExt, - getForFile: getParserForFile -}; diff --git a/packages/gitbook/src/parsers/annotateCodeBlocks.js b/packages/gitbook/src/parsers/annotateCodeBlocks.js new file mode 100644 index 0000000..92ce83a --- /dev/null +++ b/packages/gitbook/src/parsers/annotateCodeBlocks.js @@ -0,0 +1,130 @@ +const { Block, Text, Inline, INLINES, BLOCKS, MARKS } = require('markup-it'); + +const RAW_START = 'raw'; +const RAW_END = 'endraw'; + +/** + * Create a templating node. + * @param {String} expr + * @return {Node} + */ +function createTemplatingNode(expr) { + return Inline.create({ + type: INLINES.TEMPLATE, + data: { + type: 'expr', + text: expr + } + }); +} + +/** + * Escape a code block. + * @param {Block} block + * @return {Array<Node>} blocks + */ +function escapeCodeBlock(block) { + return [ + Block.create({ + type: BLOCKS.TEXT, + nodes: [ + createTemplatingNode(RAW_START) + ] + }), + block, + Block.create({ + type: BLOCKS.TEXT, + nodes: [ + createTemplatingNode(RAW_END) + ] + }) + ]; +} + + +/** + * Escape a text node. + * @param {Text} node + * @return {Array<Node>} nodes + */ +function escapeTextNode(node) { + const ranges = node.getRanges(); + + const nodes = ranges.reduce((result, range) => { + const hasCode = range.marks.some(mark => mark.type == MARKS.CODE); + const text = Text.createFromRanges([ range ]); + + if (hasCode) { + return result.concat([ + createTemplatingNode(RAW_START), + text, + createTemplatingNode(RAW_END) + ]); + } + + return result.concat([ text ]); + }, []); + + return nodes; +} + +/** + * Annotate a block container. + * @param {Node} parent + * @param {Number} levelRaw + * @return {Node} node + * @return {Number} levelRaw + */ +function annotateNode(parent, levelRaw) { + let { nodes } = parent; + + nodes = nodes.reduce((out, node) => { + if (node.type === INLINES.TEMPLATE) { + const { type, text } = node.data.toJS(); + + if (type === 'expr') { + if (text === 'raw') { + levelRaw = levelRaw + 1; + } else if (text == 'endraw') { + levelRaw = 0; + } + } + + return out.concat([ node ]); + } + + else if (node.type === BLOCKS.CODE) { + return out.concat( + levelRaw == 0 ? escapeCodeBlock(node) : [ node ] + ); + } + + else if (node.kind == 'text') { + return out.concat( + levelRaw == 0 ? escapeTextNode(node) : [ node ] + ); + } + + const result = annotateNode(node, levelRaw); + levelRaw = result.levelRaw; + return out.concat([result.node]); + }, []); + + return { + levelRaw, + node: parent.merge({ nodes }) + }; +} + +/** + * Add templating "raw" to code blocks to + * avoid nunjucks processing their content. + * + * @param {Document} document + * @return {Document} + */ +function annotateCodeBlocks(document) { + return annotateNode(document, 0).node; +} + +module.exports = annotateCodeBlocks; diff --git a/packages/gitbook/src/parsers/asciidoc.js b/packages/gitbook/src/parsers/asciidoc.js new file mode 100644 index 0000000..7425f65 --- /dev/null +++ b/packages/gitbook/src/parsers/asciidoc.js @@ -0,0 +1,72 @@ +const { State } = require('markup-it'); +const AsciidoctorJS = require('asciidoctor.js'); +const asciidoc = require('markup-it/lib/asciidoc'); + +const asciidocjs = AsciidoctorJS(); + +const FILE_EXTENSIONS = [ + '.adoc', + '.asciidoc' +]; + +/** + * Render a document as text. + * @param {Document} document + * @return {String} text + */ +function toText(document) { + const state = State.create(asciidoc); + return state.serializeDocument(document); +} + +/** + * Parse asciidoc into a document. + * @param {String} text + * @return {Document} document + */ +function toDocument(text) { + const state = State.create(asciidoc); + return state.deserializeToDocument(text); +} + +/** + * Render asciidoc to HTML. + * @param {String} text + * @return {String} html + */ +function toHTML(text) { + return asciidocjs.convert(text, { + attributes: 'showtitle' + }); +} + +/** + * Prepare a document for parsing + * @param {String} text + * @return {String} text + */ +function prepare(text) { + return text; +} + +/** + * Render asciidoc to inline HTML. + * @param {String} text + * @return {String} html + */ +function toInlineHTML(text) { + return asciidocjs.convert(text, { + doctype: 'inline', + attributes: 'showtitle' + }); +} + +module.exports = { + name: 'asciidoc', + FILE_EXTENSIONS, + prepare, + toDocument, + toText, + toHTML, + toInlineHTML +}; diff --git a/packages/gitbook/src/parsers/index.js b/packages/gitbook/src/parsers/index.js new file mode 100644 index 0000000..b92b147 --- /dev/null +++ b/packages/gitbook/src/parsers/index.js @@ -0,0 +1,46 @@ +const path = require('path'); +const { Map } = require('immutable'); + +const PARSERS = new Map({ + markdown: require('./markdown'), + asciidoc: require('./asciidoc') +}); + +const FILE_EXTENSIONS = PARSERS.reduce((result, parser) => result.concat(parser.FILE_EXTENSIONS), []); + +/** + * Return a specific parser by its name + * + * @param {String} name + * @return {Parser} parser? + */ +function getParser(name) { + return PARSERS.get(name); +} + +/** + * Return a specific parser according to an extension + * + * @param {String} ext + * @return {Parser} parser? + */ +function getByExt(ext) { + return PARSERS.find(parser => parser.FILE_EXTENSIONS.includes(ext)); +} + +/** + * Return parser for a file + * + * @param {String} ext + * @return {Parser} parser? + */ +function getForFile(filename) { + return getByExt(path.extname(filename)); +} + +module.exports = { + FILE_EXTENSIONS, + get: getParser, + getByExt, + getForFile +}; diff --git a/packages/gitbook/src/parsers/markdown.js b/packages/gitbook/src/parsers/markdown.js new file mode 100644 index 0000000..e110eb7 --- /dev/null +++ b/packages/gitbook/src/parsers/markdown.js @@ -0,0 +1,75 @@ +const { State } = require('markup-it'); +const markdown = require('markup-it/lib/markdown'); +const html = require('markup-it/lib/html'); +const annotateCodeBlocks = require('./annotateCodeBlocks'); + +const FILE_EXTENSIONS = [ + '.md', + '.markdown', + '.mdown' +]; + +/** + * Render a document as markdown. + * @param {Document} document + * @return {String} text + */ +function toText(document) { + const state = State.create(markdown); + return state.serializeDocument(document); +} + +/** + * Parse markdown into a document. + * @param {String} text + * @return {Document} document + */ +function toDocument(text) { + const state = State.create(markdown); + return state.deserializeToDocument(text); +} + +/** + * Prepare a document for parsing + * @param {String} text + * @return {String} text + */ +function prepare(text) { + let doc = toDocument(text); + doc = annotateCodeBlocks(doc); + return toText(doc); +} + +/** + * Render markdown to HTML. + * @param {String} text + * @return {String} html + */ +function toHTML(text) { + const document = toDocument(text); + const state = State.create(html); + + return state.serializeDocument(document); +} + +/** + * Render markdown to inline HTML. + * @param {String} text + * @return {String} html + */ +function toInlineHTML(text) { + const document = toDocument(text); + const state = State.create(html); + + return state.serializeDocument(document); +} + +module.exports = { + name: 'markdown', + FILE_EXTENSIONS, + prepare, + toText, + toDocument, + toHTML, + toInlineHTML +}; diff --git a/packages/gitbook/src/plugins/__tests__/findInstalled.js b/packages/gitbook/src/plugins/__tests__/findInstalled.js index e787761..bf4c057 100644 --- a/packages/gitbook/src/plugins/__tests__/findInstalled.js +++ b/packages/gitbook/src/plugins/__tests__/findInstalled.js @@ -1,20 +1,20 @@ const path = require('path'); const Immutable = require('immutable'); -describe('findInstalled', function() { +describe('findInstalled', () => { const findInstalled = require('../findInstalled'); - it('must list default plugins for gitbook directory', function() { + it('must list default plugins for gitbook directory', () => { // Read gitbook-plugins from package.json const pkg = require(path.resolve(__dirname, '../../../package.json')); const gitbookPlugins = Immutable.Seq(pkg.dependencies) - .filter(function(v, k) { + .filter((v, k) => { return k.indexOf('gitbook-plugin') === 0; }) .cacheResult(); return findInstalled(path.resolve(__dirname, '../../../')) - .then(function(plugins) { + .then((plugins) => { expect(plugins.size >= gitbookPlugins.size).toBeTruthy(); expect(plugins.has('highlight')).toBe(true); diff --git a/packages/gitbook/src/plugins/__tests__/installPlugins.js b/packages/gitbook/src/plugins/__tests__/installPlugins.js index 26f135d..f062090 100644 --- a/packages/gitbook/src/plugins/__tests__/installPlugins.js +++ b/packages/gitbook/src/plugins/__tests__/installPlugins.js @@ -30,7 +30,7 @@ describe('installPlugins', () => { it('must install all plugins from NPM', () => { return installPlugins(book) - .then(function(n) { + .then((n) => { expect(n).toBe(2); }); }); diff --git a/packages/gitbook/src/plugins/__tests__/locateRootFolder.js b/packages/gitbook/src/plugins/__tests__/locateRootFolder.js index 54e095b..eead6f4 100644 --- a/packages/gitbook/src/plugins/__tests__/locateRootFolder.js +++ b/packages/gitbook/src/plugins/__tests__/locateRootFolder.js @@ -1,8 +1,8 @@ const path = require('path'); const locateRootFolder = require('../locateRootFolder'); -describe('locateRootFolder', function() { - it('should correctly resolve the node_modules for gitbook', function() { +describe('locateRootFolder', () => { + it('should correctly resolve the node_modules for gitbook', () => { expect(locateRootFolder()).toBe( path.resolve(__dirname, '../../../') ); diff --git a/packages/gitbook/src/plugins/__tests__/resolveVersion.js b/packages/gitbook/src/plugins/__tests__/resolveVersion.js index 949d078..2f8232a 100644 --- a/packages/gitbook/src/plugins/__tests__/resolveVersion.js +++ b/packages/gitbook/src/plugins/__tests__/resolveVersion.js @@ -1,21 +1,21 @@ const PluginDependency = require('../../models/pluginDependency'); const resolveVersion = require('../resolveVersion'); -describe('resolveVersion', function() { - it('must skip resolving and return non-semver versions', function() { +describe('resolveVersion', () => { + it('must skip resolving and return non-semver versions', () => { const plugin = PluginDependency.createFromString('ga@git+ssh://samy@github.com/GitbookIO/plugin-ga.git'); return resolveVersion(plugin) - .then(function(version) { + .then((version) => { expect(version).toBe('git+ssh://samy@github.com/GitbookIO/plugin-ga.git'); }); }); - it('must resolve a normal plugin dependency', function() { + it('must resolve a normal plugin dependency', () => { const plugin = PluginDependency.createFromString('ga@>0.9.0 < 1.0.1'); return resolveVersion(plugin) - .then(function(version) { + .then((version) => { expect(version).toBe('1.0.0'); }); }); diff --git a/packages/gitbook/src/plugins/__tests__/sortDependencies.js b/packages/gitbook/src/plugins/__tests__/sortDependencies.js index a08d59d..f374422 100644 --- a/packages/gitbook/src/plugins/__tests__/sortDependencies.js +++ b/packages/gitbook/src/plugins/__tests__/sortDependencies.js @@ -2,8 +2,8 @@ const PluginDependency = require('../../models/pluginDependency'); const sortDependencies = require('../sortDependencies'); const toNames = require('../toNames'); -describe('sortDependencies', function() { - it('must load themes after plugins', function() { +describe('sortDependencies', () => { + it('must load themes after plugins', () => { const allPlugins = PluginDependency.listFromArray([ 'hello', 'theme-test', @@ -20,7 +20,7 @@ describe('sortDependencies', function() { ]); }); - it('must keep order of themes', function() { + it('must keep order of themes', () => { const allPlugins = PluginDependency.listFromArray([ 'theme-test', 'theme-test1', diff --git a/packages/gitbook/src/plugins/__tests__/validatePlugin.js b/packages/gitbook/src/plugins/__tests__/validatePlugin.js index a2bd23b..fe4e65c 100644 --- a/packages/gitbook/src/plugins/__tests__/validatePlugin.js +++ b/packages/gitbook/src/plugins/__tests__/validatePlugin.js @@ -2,14 +2,14 @@ const Promise = require('../../utils/promise'); const Plugin = require('../../models/plugin'); const validatePlugin = require('../validatePlugin'); -describe('validatePlugin', function() { - it('must not validate a not loaded plugin', function() { +describe('validatePlugin', () => { + it('must not validate a not loaded plugin', () => { const plugin = Plugin.createFromString('test'); return validatePlugin(plugin) - .then(function() { + .then(() => { throw new Error('Should not be validate'); - }, function(err) { + }, (err) => { return Promise(); }); }); diff --git a/packages/gitbook/src/plugins/findForBook.js b/packages/gitbook/src/plugins/findForBook.js index 8668d1d..833f7b7 100644 --- a/packages/gitbook/src/plugins/findForBook.js +++ b/packages/gitbook/src/plugins/findForBook.js @@ -21,9 +21,9 @@ function findForBook(book) { ]) // Merge all plugins - .then(function(results) { + .then((results) => { return List(results) - .reduce(function(out, result) { + .reduce((out, result) => { return out.merge(result); }, OrderedMap()); }) diff --git a/packages/gitbook/src/plugins/installPlugin.js b/packages/gitbook/src/plugins/installPlugin.js index 9834d05..edc145f 100644 --- a/packages/gitbook/src/plugins/installPlugin.js +++ b/packages/gitbook/src/plugins/installPlugin.js @@ -24,7 +24,7 @@ function installPlugin(book, plugin) { // Find a version to install return resolveVersion(plugin) - .then(function(version) { + .then((version) => { if (!version) { throw new Error('Found no satisfactory version for plugin "' + name + '" with requirement "' + requirement + '"'); } @@ -36,7 +36,7 @@ function installPlugin(book, plugin) { return exec(command, { cwd: installFolder }); }) - .then(function() { + .then(() => { logger.info.ok('plugin "' + name + '" installed with success'); }); } diff --git a/packages/gitbook/src/plugins/installPlugins.js b/packages/gitbook/src/plugins/installPlugins.js index 9d2520f..831834c 100644 --- a/packages/gitbook/src/plugins/installPlugins.js +++ b/packages/gitbook/src/plugins/installPlugins.js @@ -15,8 +15,8 @@ function installPlugins(book) { // Remove default plugins // (only if version is same as installed) - plugins = plugins.filterNot(function(plugin) { - const dependency = DEFAULT_PLUGINS.find(function(dep) { + plugins = plugins.filterNot((plugin) => { + const dependency = DEFAULT_PLUGINS.find((dep) => { return dep.getName() === plugin.getName(); }); @@ -37,7 +37,7 @@ function installPlugins(book) { logger.info.ln('installing', plugins.size, 'plugins from registry'); - return Promise.forEach(plugins, function(plugin) { + return Promise.forEach(plugins, (plugin) => { return installPlugin(book, plugin); }) .thenResolve(plugins.size); diff --git a/packages/gitbook/src/plugins/listDependencies.js b/packages/gitbook/src/plugins/listDependencies.js index 3930ae7..6845f10 100644 --- a/packages/gitbook/src/plugins/listDependencies.js +++ b/packages/gitbook/src/plugins/listDependencies.js @@ -11,10 +11,10 @@ const sortDependencies = require('./sortDependencies'); function listDependencies(deps) { // Extract list of plugins to disable (starting with -) const toRemove = deps - .filter(function(plugin) { + .filter((plugin) => { return !plugin.isEnabled(); }) - .map(function(plugin) { + .map((plugin) => { return plugin.getName(); }); @@ -22,7 +22,7 @@ function listDependencies(deps) { deps = deps.concat(DEFAULT_PLUGINS); // Remove plugins - deps = deps.filterNot(function(plugin) { + deps = deps.filterNot((plugin) => { return toRemove.includes(plugin.getName()); }); diff --git a/packages/gitbook/src/plugins/loadForBook.js b/packages/gitbook/src/plugins/loadForBook.js index 0baa78e..2ddcd7d 100644 --- a/packages/gitbook/src/plugins/loadForBook.js +++ b/packages/gitbook/src/plugins/loadForBook.js @@ -20,15 +20,15 @@ function loadForBook(book) { // List all plugins installed in the book return findForBook(book) - .then(function(installedMap) { + .then((installedMap) => { const missing = []; - let plugins = requirements.reduce(function(result, dep) { + let plugins = requirements.reduce((result, dep) => { const name = dep.getName(); const installed = installedMap.get(name); if (installed) { const deps = installedMap - .filter(function(plugin) { + .filter((plugin) => { return plugin.getParent() === name; }) .toArray(); @@ -44,7 +44,7 @@ function loadForBook(book) { // Convert plugins list to a map plugins = Immutable.List(plugins) - .map(function(plugin) { + .map((plugin) => { return [ plugin.getName(), plugin @@ -63,7 +63,7 @@ function loadForBook(book) { throw new Error('Couldn\'t locate plugins "' + missing.join(', ') + '", Run \'gitbook install\' to install plugins from registry.'); } - return Promise.map(plugins, function(plugin) { + return Promise.map(plugins, (plugin) => { return loadPlugin(book, plugin); }); }); diff --git a/packages/gitbook/src/plugins/loadPlugin.js b/packages/gitbook/src/plugins/loadPlugin.js index 167587a..2ebc9ca 100644 --- a/packages/gitbook/src/plugins/loadPlugin.js +++ b/packages/gitbook/src/plugins/loadPlugin.js @@ -30,7 +30,7 @@ function loadPlugin(book, plugin) { // Try loading plugins from different location let p = Promise() - .then(function() { + .then(() => { let packageContent; let packageMain; let content; diff --git a/packages/gitbook/src/plugins/resolveVersion.js b/packages/gitbook/src/plugins/resolveVersion.js index a241c23..52bf63f 100644 --- a/packages/gitbook/src/plugins/resolveVersion.js +++ b/packages/gitbook/src/plugins/resolveVersion.js @@ -38,23 +38,23 @@ function resolveVersion(plugin) { } return initNPM() - .then(function() { + .then(() => { return Promise.nfcall(npm.commands.view, [npmId + '@' + requiredVersion, 'engines'], true); }) - .then(function(versions) { + .then((versions) => { versions = Map(versions).entrySeq(); const result = versions - .map(function(entry) { + .map((entry) => { return { version: entry[0], gitbook: (entry[1].engines || {}).gitbook }; }) - .filter(function(v) { + .filter((v) => { return v.gitbook && gitbook.satisfies(v.gitbook); }) - .sort(function(v1, v2) { + .sort((v1, v2) => { return semver.lt(v1.version, v2.version) ? 1 : -1; }) .get(0); diff --git a/packages/gitbook/src/plugins/toNames.js b/packages/gitbook/src/plugins/toNames.js index 422a24d..f2058a6 100644 --- a/packages/gitbook/src/plugins/toNames.js +++ b/packages/gitbook/src/plugins/toNames.js @@ -7,7 +7,7 @@ */ function toNames(plugins) { return plugins - .map(function(plugin) { + .map((plugin) => { return plugin.getName(); }) .toArray(); diff --git a/packages/gitbook/src/plugins/validateConfig.js b/packages/gitbook/src/plugins/validateConfig.js index 82a2507..4937663 100644 --- a/packages/gitbook/src/plugins/validateConfig.js +++ b/packages/gitbook/src/plugins/validateConfig.js @@ -63,7 +63,7 @@ function validatePluginConfig(book, plugin) { * @return {Promise<Book>} */ function validateConfig(book, plugins) { - return Promise.reduce(plugins, function(newBook, plugin) { + return Promise.reduce(plugins, (newBook, plugin) => { return validatePluginConfig(newBook, plugin); }, book); } diff --git a/packages/gitbook/src/templating/__tests__/conrefsLoader.js b/packages/gitbook/src/templating/__tests__/conrefsLoader.js index 1b8e92f..f08baec 100644 --- a/packages/gitbook/src/templating/__tests__/conrefsLoader.js +++ b/packages/gitbook/src/templating/__tests__/conrefsLoader.js @@ -64,7 +64,7 @@ describe('ConrefsLoader', () => { }); }); - describe('Absolute', function() { + describe('Absolute', () => { it('should resolve absolute filepath', () => { return renderTemplate(engine, fileName, '{% include "/include.md" %}') .then((out) => { diff --git a/packages/gitbook/src/templating/__tests__/replaceShortcuts.js b/packages/gitbook/src/templating/__tests__/replaceShortcuts.js index 1126f91..8a01292 100644 --- a/packages/gitbook/src/templating/__tests__/replaceShortcuts.js +++ b/packages/gitbook/src/templating/__tests__/replaceShortcuts.js @@ -3,7 +3,7 @@ const Immutable = require('immutable'); const TemplateBlock = require('../../models/templateBlock'); const replaceShortcuts = require('../replaceShortcuts'); -describe('replaceShortcuts', function() { +describe('replaceShortcuts', () => { const blocks = Immutable.List([ TemplateBlock.create('math', { shortcuts: { @@ -14,17 +14,17 @@ describe('replaceShortcuts', function() { }) ]); - it('should correctly replace inline matches by block', function() { + it('should correctly replace inline matches by block', () => { const content = replaceShortcuts(blocks, 'test.md', 'Hello $$a = b$$'); expect(content).toBe('Hello {% math %}a = b{% endmath %}'); }); - it('should correctly replace multiple inline matches by block', function() { + it('should correctly replace multiple inline matches by block', () => { const content = replaceShortcuts(blocks, 'test.md', 'Hello $$a = b$$ and $$c = d$$'); expect(content).toBe('Hello {% math %}a = b{% endmath %} and {% math %}c = d{% endmath %}'); }); - it('should correctly replace block matches', function() { + it('should correctly replace block matches', () => { const content = replaceShortcuts(blocks, 'test.md', 'Hello\n$$\na = b\n$$\n'); expect(content).toBe('Hello\n{% math %}\na = b\n{% endmath %}\n'); }); diff --git a/packages/gitbook/src/templating/conrefsLoader.js b/packages/gitbook/src/templating/conrefsLoader.js index 3660d17..3fb2e4e 100644 --- a/packages/gitbook/src/templating/conrefsLoader.js +++ b/packages/gitbook/src/templating/conrefsLoader.js @@ -31,7 +31,7 @@ const ConrefsLoader = nunjucks.Loader.extend({ const that = this; this.git.resolve(sourceURL) - .then(function(filepath) { + .then((filepath) => { // Is local file if (!filepath) { filepath = path.resolve(sourceURL); @@ -41,7 +41,7 @@ const ConrefsLoader = nunjucks.Loader.extend({ // Read file from absolute path return fs.readFile(filepath) - .then(function(source) { + .then((source) => { source = source.toString('utf8'); if (that.transformFn) { @@ -50,7 +50,7 @@ const ConrefsLoader = nunjucks.Loader.extend({ return source; }) - .then(function(source) { + .then((source) => { return { src: source, path: filepath diff --git a/packages/gitbook/src/templating/listShortcuts.js b/packages/gitbook/src/templating/listShortcuts.js index 099b709..f65c701 100644 --- a/packages/gitbook/src/templating/listShortcuts.js +++ b/packages/gitbook/src/templating/listShortcuts.js @@ -17,13 +17,13 @@ function listShortcuts(blocks, filePath) { } return blocks - .map(function(block) { + .map((block) => { return block.getShortcuts(); }) - .filter(function(shortcuts) { + .filter((shortcuts) => { return ( shortcuts && - shortcuts.acceptParser(parser.getName()) + shortcuts.acceptParser(parser.name) ); }); } diff --git a/packages/gitbook/src/templating/renderFile.js b/packages/gitbook/src/templating/renderFile.js index a2463f8..11166e9 100644 --- a/packages/gitbook/src/templating/renderFile.js +++ b/packages/gitbook/src/templating/renderFile.js @@ -17,7 +17,7 @@ function renderTemplateFile(engine, filePath, context) { const resolvedFilePath = loader.resolve(null, filePath); return Promise() - .then(function() { + .then(() => { if (!loader.async) { return loader.getSource(resolvedFilePath); } @@ -26,7 +26,7 @@ function renderTemplateFile(engine, filePath, context) { loader.getSource(resolvedFilePath, deferred.makeNodeResolver()); return deferred.promise; }) - .then(function(result) { + .then((result) => { if (!result) { throw error.TemplateError(new Error('Not found'), { filename: filePath diff --git a/packages/gitbook/src/templating/replaceShortcuts.js b/packages/gitbook/src/templating/replaceShortcuts.js index 25f598f..b162e95 100644 --- a/packages/gitbook/src/templating/replaceShortcuts.js +++ b/packages/gitbook/src/templating/replaceShortcuts.js @@ -18,7 +18,7 @@ function applyShortcut(content, shortcut) { escapeStringRegexp(start) + '([\\s\\S]*?[^\\$])' + escapeStringRegexp(end), 'g' ); - return content.replace(regex, function(all, match) { + return content.replace(regex, (all, match) => { return '{% ' + tagStart + ' %}' + match + '{% ' + tagEnd + ' %}'; }); } diff --git a/packages/gitbook/src/utils/__tests__/git.js b/packages/gitbook/src/utils/__tests__/git.js index 29be4a1..3e64c9a 100644 --- a/packages/gitbook/src/utils/__tests__/git.js +++ b/packages/gitbook/src/utils/__tests__/git.js @@ -46,7 +46,7 @@ describe('Git', () => { it('should clone an HTTPS url', () => { const git = new Git(); return git.resolve('git+https://gist.github.com/69ea4542e4c8967d2fa7.git/test.md') - .then(function(filename) { + .then((filename) => { expect(path.extname(filename)).toBe('.md'); }); }); diff --git a/packages/gitbook/src/utils/__tests__/location.js b/packages/gitbook/src/utils/__tests__/location.js index a565adb..163cca3 100644 --- a/packages/gitbook/src/utils/__tests__/location.js +++ b/packages/gitbook/src/utils/__tests__/location.js @@ -1,7 +1,7 @@ const LocationUtils = require('../location'); -describe('LocationUtils', function() { - it('should correctly test external location', function() { +describe('LocationUtils', () => { + it('should correctly test external location', () => { expect(LocationUtils.isExternal('http://google.fr')).toBe(true); expect(LocationUtils.isExternal('https://google.fr')).toBe(true); expect(LocationUtils.isExternal('test.md')).toBe(false); @@ -10,7 +10,7 @@ describe('LocationUtils', function() { expect(LocationUtils.isExternal('data:image/png')).toBe(false); }); - it('should correctly test data:uri location', function() { + it('should correctly test data:uri location', () => { expect(LocationUtils.isDataURI('data:image/png')).toBe(true); expect(LocationUtils.isDataURI('http://google.fr')).toBe(false); expect(LocationUtils.isDataURI('https://google.fr')).toBe(false); @@ -18,77 +18,77 @@ describe('LocationUtils', function() { expect(LocationUtils.isDataURI('data.md')).toBe(false); }); - it('should correctly detect anchor location', function() { + it('should correctly detect anchor location', () => { expect(LocationUtils.isAnchor('#test')).toBe(true); expect(LocationUtils.isAnchor(' #test')).toBe(true); expect(LocationUtils.isAnchor('https://google.fr#test')).toBe(false); expect(LocationUtils.isAnchor('test.md#test')).toBe(false); }); - describe('.relative', function() { - it('should resolve to a relative path (same folder)', function() { + describe('.relative', () => { + it('should resolve to a relative path (same folder)', () => { expect(LocationUtils.relative('links/', 'links/test.md')).toBe('test.md'); }); - it('should resolve to a relative path (parent folder)', function() { + it('should resolve to a relative path (parent folder)', () => { expect(LocationUtils.relative('links/', 'test.md')).toBe('../test.md'); }); - it('should resolve to a relative path (child folder)', function() { + it('should resolve to a relative path (child folder)', () => { expect(LocationUtils.relative('links/', 'links/hello/test.md')).toBe('hello/test.md'); }); }); - describe('.flatten', function() { - it('should remove leading slash', function() { + describe('.flatten', () => { + it('should remove leading slash', () => { expect(LocationUtils.flatten('/test.md')).toBe('test.md'); expect(LocationUtils.flatten('/hello/cool.md')).toBe('hello/cool.md'); }); - it('should remove leading slashes', function() { + it('should remove leading slashes', () => { expect(LocationUtils.flatten('///test.md')).toBe('test.md'); }); - it('should not break paths', function() { + it('should not break paths', () => { expect(LocationUtils.flatten('hello/cool.md')).toBe('hello/cool.md'); }); }); - describe('.toAbsolute', function() { - it('should correctly transform as absolute', function() { + describe('.toAbsolute', () => { + it('should correctly transform as absolute', () => { expect(LocationUtils.toAbsolute('http://google.fr')).toBe('http://google.fr'); expect(LocationUtils.toAbsolute('test.md', './', './')).toBe('test.md'); expect(LocationUtils.toAbsolute('folder/test.md', './', './')).toBe('folder/test.md'); }); - it('should correctly handle windows path', function() { + it('should correctly handle windows path', () => { expect(LocationUtils.toAbsolute('folder\\test.md', './', './')).toBe('folder/test.md'); }); - it('should correctly handle absolute path', function() { + it('should correctly handle absolute path', () => { expect(LocationUtils.toAbsolute('/test.md', './', './')).toBe('test.md'); expect(LocationUtils.toAbsolute('/test.md', 'test', 'test')).toBe('../test.md'); expect(LocationUtils.toAbsolute('/sub/test.md', 'test', 'test')).toBe('../sub/test.md'); expect(LocationUtils.toAbsolute('/test.png', 'folder', '')).toBe('test.png'); }); - it('should correctly handle absolute path (windows)', function() { + it('should correctly handle absolute path (windows)', () => { expect(LocationUtils.toAbsolute('\\test.png', 'folder', '')).toBe('test.png'); }); - it('should resolve path starting by "/" in root directory', function() { + it('should resolve path starting by "/" in root directory', () => { expect( LocationUtils.toAbsolute('/test/hello.md', './', './') ).toBe('test/hello.md'); }); - it('should resolve path starting by "/" in child directory', function() { + it('should resolve path starting by "/" in child directory', () => { expect( LocationUtils.toAbsolute('/test/hello.md', './hello', './') ).toBe('test/hello.md'); }); - it('should resolve path starting by "/" in child directory, with same output directory', function() { + it('should resolve path starting by "/" in child directory, with same output directory', () => { expect( LocationUtils.toAbsolute('/test/hello.md', './hello', './hello') ).toBe('../test/hello.md'); diff --git a/packages/gitbook/src/utils/__tests__/path.js b/packages/gitbook/src/utils/__tests__/path.js index 1f8a1d3..df4b5ea 100644 --- a/packages/gitbook/src/utils/__tests__/path.js +++ b/packages/gitbook/src/utils/__tests__/path.js @@ -1,15 +1,15 @@ const path = require('path'); -describe('Paths', function() { +describe('Paths', () => { const PathUtils = require('..//path'); - describe('setExtension', function() { - it('should correctly change extension of filename', function() { + describe('setExtension', () => { + it('should correctly change extension of filename', () => { expect(PathUtils.setExtension('test.md', '.html')).toBe('test.html'); expect(PathUtils.setExtension('test.md', '.json')).toBe('test.json'); }); - it('should correctly change extension of path', function() { + it('should correctly change extension of path', () => { expect(PathUtils.setExtension('hello/test.md', '.html')).toBe(path.normalize('hello/test.html')); expect(PathUtils.setExtension('hello/test.md', '.json')).toBe(path.normalize('hello/test.json')); }); diff --git a/packages/gitbook/src/utils/command.js b/packages/gitbook/src/utils/command.js index 5533ca8..05e10cf 100644 --- a/packages/gitbook/src/utils/command.js +++ b/packages/gitbook/src/utils/command.js @@ -13,7 +13,7 @@ const Promise = require('./promise'); function exec(command, options) { const d = Promise.defer(); - const child = childProcess.exec(command, options, function(err, stdout, stderr) { + const child = childProcess.exec(command, options, (err, stdout, stderr) => { if (!err) { return d.resolve(); } @@ -22,11 +22,11 @@ function exec(command, options) { d.reject(err); }); - child.stdout.on('data', function(data) { + child.stdout.on('data', (data) => { d.notify(data); }); - child.stderr.on('data', function(data) { + child.stderr.on('data', (data) => { d.notify(data); }); @@ -45,19 +45,19 @@ function spawnCmd(command, args, options) { const d = Promise.defer(); const child = spawn(command, args, options); - child.on('error', function(error) { + child.on('error', (error) => { return d.reject(error); }); - child.stdout.on('data', function(data) { + child.stdout.on('data', (data) => { d.notify(data); }); - child.stderr.on('data', function(data) { + child.stderr.on('data', (data) => { d.notify(data); }); - child.on('close', function(code) { + child.on('close', (code) => { if (code === 0) { d.resolve(); } else { diff --git a/packages/gitbook/src/utils/fs.js b/packages/gitbook/src/utils/fs.js index 17b2ebb..f536e0b 100644 --- a/packages/gitbook/src/utils/fs.js +++ b/packages/gitbook/src/utils/fs.js @@ -20,16 +20,16 @@ function writeStream(filename, st) { wstream.removeAllListeners(); }; - wstream.on('finish', function() { + wstream.on('finish', () => { cleanup(); d.resolve(); }); - wstream.on('error', function(err) { + wstream.on('error', (err) => { cleanup(); d.reject(err); }); - st.on('error', function(err) { + st.on('error', (err) => { cleanup(); d.reject(err); }); @@ -43,7 +43,7 @@ function writeStream(filename, st) { function fileExists(filename) { const d = Promise.defer(); - fs.exists(filename, function(exists) { + fs.exists(filename, (exists) => { d.resolve(exists); }); @@ -106,7 +106,7 @@ function rmDir(base) { */ function assertFile(filePath, generator) { return fileExists(filePath) - .then(function(exists) { + .then((exists) => { if (exists) return; return generator(); @@ -137,10 +137,10 @@ function pickFile(rootFolder, fileName) { */ function ensureFolder(rootFolder) { return rmDir(rootFolder) - .fail(function() { + .fail(() => { return Promise(); }) - .then(function() { + .then(() => { return Promise.nfcall(mkdirp, rootFolder); }); } diff --git a/packages/gitbook/src/utils/git.js b/packages/gitbook/src/utils/git.js index 2b2a3e3..3e11ee4 100644 --- a/packages/gitbook/src/utils/git.js +++ b/packages/gitbook/src/utils/git.js @@ -30,7 +30,7 @@ class Git { } return fs.tmpDir() - .then(function(dir) { + .then((dir) => { that.tmpDir = dir; }); } @@ -47,7 +47,7 @@ class Git { return this.allocateDir() // Return or clone the git repo - .then(function() { + .then(() => { // Unique ID for repo/ref combinaison const repoId = that.repoID(host, ref); @@ -60,7 +60,7 @@ class Git { return command.exec('git clone ' + host + ' ' + repoPath) // Checkout reference if specified - .then(function() { + .then(() => { that.cloned[repoId] = true; if (!ref) return; @@ -86,7 +86,7 @@ class Git { // Clone or get from cache return this.clone(giturl.host, giturl.ref) - .then(function(repo) { + .then((repo) => { return path.resolve(repo, giturl.filepath); }); } diff --git a/packages/gitbook/src/utils/images.js b/packages/gitbook/src/utils/images.js index 808be63..0d326ef 100644 --- a/packages/gitbook/src/utils/images.js +++ b/packages/gitbook/src/utils/images.js @@ -8,7 +8,7 @@ function convertSVGToPNG(source, dest, options) { if (!fs.existsSync(source)) return Promise.reject(new error.FileNotFoundError({ filename: source })); return command.spawn('svgexport', [source, dest]) - .fail(function(err) { + .fail((err) => { if (err.code == 'ENOENT') { err = error.RequireInstallError({ cmd: 'svgexport', @@ -17,7 +17,7 @@ function convertSVGToPNG(source, dest, options) { } throw err; }) - .then(function() { + .then(() => { if (fs.existsSync(dest)) return; throw new Error('Error converting ' + source + ' into ' + dest); @@ -30,9 +30,9 @@ function convertSVGBufferToPNG(buf, dest) { return fs.tmpFile({ postfix: '.svg' }) - .then(function(tmpSvg) { + .then((tmpSvg) => { return fs.writeFile(tmpSvg, buf) - .then(function() { + .then(() => { return convertSVGToPNG(tmpSvg, dest); }); }); @@ -46,7 +46,7 @@ function convertInlinePNG(source, dest) { const buf = new Buffer(base64data, 'base64'); return fs.writeFile(dest, buf) - .then(function() { + .then(() => { if (fs.existsSync(dest)) return; throw new Error('Error converting ' + source + ' into ' + dest); diff --git a/packages/gitbook/src/utils/logger.js b/packages/gitbook/src/utils/logger.js index 25f8517..24fe5d7 100644 --- a/packages/gitbook/src/utils/logger.js +++ b/packages/gitbook/src/utils/logger.js @@ -103,7 +103,7 @@ Logger.prototype.writeLn = function(msg) { Logger.prototype.log = function(level, ...args) { if (level < this.logLevel) return; - const levelKey = LEVELS.findKey(function(v) { + const levelKey = LEVELS.findKey((v) => { return v === level; }); let msg = this.format(...args); @@ -156,10 +156,10 @@ Logger.prototype.promise = function(level, p) { const that = this; return p - .then(function(st) { + .then((st) => { that.ok(level); return st; - }, function(err) { + }, (err) => { that.fail(level); throw err; }); diff --git a/packages/gitbook/src/utils/path.js b/packages/gitbook/src/utils/path.js index 01c2cbf..03328e8 100644 --- a/packages/gitbook/src/utils/path.js +++ b/packages/gitbook/src/utils/path.js @@ -25,7 +25,7 @@ function isInRoot(root, filename) { // Throw error if file is outside this folder function resolveInRoot(root, ...args) { const input = args - .reduce(function(current, p) { + .reduce((current, p) => { // Handle path relative to book root ("/README.md") if (p[0] == '/' || p[0] == '\\') return p.slice(1); diff --git a/packages/gitbook/src/utils/promise.js b/packages/gitbook/src/utils/promise.js index 8cbbd47..561ab7e 100644 --- a/packages/gitbook/src/utils/promise.js +++ b/packages/gitbook/src/utils/promise.js @@ -16,9 +16,9 @@ if (process.env.DEBUG || process.env.CI) { function reduce(arr, iter, base) { arr = Immutable.Iterable.isIterable(arr) ? arr : Immutable.List(arr); - return arr.reduce(function(prev, elem, key) { + return arr.reduce((prev, elem, key) => { return prev - .then(function(val) { + .then((val) => { return iter(val, elem, key); }); }, Q(base)); @@ -32,7 +32,7 @@ function reduce(arr, iter, base) { * @return {Promise} */ function forEach(arr, iter) { - return reduce(arr, function(val, el, key) { + return reduce(arr, (val, el, key) => { return iter(el, key); }); } @@ -45,9 +45,9 @@ function forEach(arr, iter) { * @return {Promise} */ function serie(arr, iter, base) { - return reduce(arr, function(before, item, key) { + return reduce(arr, (before, item, key) => { return Q(iter(item, key)) - .then(function(r) { + .then((r) => { before.push(r); return before; }); @@ -64,8 +64,8 @@ function serie(arr, iter, base) { function some(arr, iter) { arr = Immutable.List(arr); - return arr.reduce(function(prev, elem, i) { - return prev.then(function(val) { + return arr.reduce((prev, elem, i) => { + return prev.then((val) => { if (val) return val; return iter(elem, i); @@ -81,9 +81,9 @@ function some(arr, iter) { * @return {Promise<List>} */ function mapAsList(arr, iter) { - return reduce(arr, function(prev, entry, i) { + return reduce(arr, (prev, entry, i) => { return Q(iter(entry, i)) - .then(function(out) { + .then((out) => { prev.push(out); return prev; }); @@ -104,18 +104,18 @@ function map(arr, iter) { type = 'OrderedMap'; } - return mapAsList(arr, function(value, key) { + return mapAsList(arr, (value, key) => { return Q(iter(value, key)) - .then(function(result) { + .then((result) => { return [key, result]; }); }) - .then(function(result) { + .then((result) => { return Immutable[type](result); }); } else { return mapAsList(arr, iter) - .then(function(result) { + .then((result) => { return Immutable.List(result); }); } @@ -131,7 +131,7 @@ function map(arr, iter) { function wrap(func) { return function(...args) { return Q() - .then(function() { + .then(() => { return func(...args); }); }; diff --git a/packages/gitbook/src/utils/reducedObject.js b/packages/gitbook/src/utils/reducedObject.js index 196a72c..fc77cdd 100644 --- a/packages/gitbook/src/utils/reducedObject.js +++ b/packages/gitbook/src/utils/reducedObject.js @@ -11,7 +11,7 @@ function reducedObject(defaultVersion, currentVersion) { return currentVersion; } - return currentVersion.reduce(function(result, value, key) { + return currentVersion.reduce((result, value, key) => { const defaultValue = defaultVersion.get(key); if (Immutable.Map.isMap(value)) { diff --git a/packages/gitbook/src/utils/timing.js b/packages/gitbook/src/utils/timing.js index 38ffd00..83add9f 100644 --- a/packages/gitbook/src/utils/timing.js +++ b/packages/gitbook/src/utils/timing.js @@ -78,11 +78,11 @@ function dump(logger) { Immutable.Map(timers) .valueSeq() - .sortBy(function(timer) { + .sortBy((timer) => { measured += timer.total; return timer.total; }) - .forEach(function(timer) { + .forEach((timer) => { const percent = (timer.total * 100) / totalDuration; logger.debug.ln((percent.toFixed(1)) + '% of time spent in "' + timer.type + '" (' + timer.count + ' times) :'); |