diff options
author | Samy Pessé <samypesse@gmail.com> | 2016-01-28 16:27:29 +0100 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2016-01-28 16:27:29 +0100 |
commit | a063cc1a53bede0a869b184f5ec4793ce300ae01 (patch) | |
tree | 15b960ffaf0e3058cf7c5cc6e272ae4ad8f56731 | |
parent | 36f2f5d52e54c03036f05225df3f58e9833f3e71 (diff) | |
download | gitbook-a063cc1a53bede0a869b184f5ec4793ce300ae01.zip gitbook-a063cc1a53bede0a869b184f5ec4793ce300ae01.tar.gz gitbook-a063cc1a53bede0a869b184f5ec4793ce300ae01.tar.bz2 |
Add base for langs parsing
-rw-r--r-- | lib/backbone/glossary.js | 3 | ||||
-rw-r--r-- | lib/backbone/langs.js | 54 | ||||
-rw-r--r-- | lib/book.js | 51 | ||||
-rw-r--r-- | lib/output.js | 7 |
4 files changed, 108 insertions, 7 deletions
diff --git a/lib/backbone/glossary.js b/lib/backbone/glossary.js index 22c4d42..9aed1ac 100644 --- a/lib/backbone/glossary.js +++ b/lib/backbone/glossary.js @@ -32,6 +32,9 @@ GlossaryEntry.prototype.getId = function() { }; +/* +A glossary is a list of entries stored in a GLOSSARY.md file +*/ function Glossary() { BackboneFile.apply(this, arguments); diff --git a/lib/backbone/langs.js b/lib/backbone/langs.js index 2818519..a40bd80 100644 --- a/lib/backbone/langs.js +++ b/lib/backbone/langs.js @@ -1,15 +1,65 @@ +var _ = require('lodash'); +var path = require('path'); +var util = require('util'); +var BackboneFile = require('./file'); +function Language(title, folder) { + var that = this; + + this.title = title; + this.folder = folder; + + Object.defineProperty(this, 'id', { + get: function() { + return path.basename(that.folder); + } + }); +} + +/* +A Langs is a list of languages stored in a LANGS.md file +*/ function Langs() { - if (!(this instanceof Langs)) return new Langs(); + BackboneFile.apply(this, arguments); this.languages = []; } +util.inherits(Langs, BackboneFile); Langs.prototype.type = 'langs'; +// Parse the readme content +Langs.prototype.parse = function(content) { + var that = this; + + return this.parser.langs(content) + .then(function(langs) { + that.languages = _.map(langs, function(entry) { + return new Language(entry.title, entry.path); + }); + }); +}; + +// Return the list of languages +Langs.prototype.list = function() { + return this.languages; +}; + +// Return default/main language for the book +Langs.prototype.getDefault = function() { + return _.first(this.languages); +}; + +// Return true if a language is the default one +// "lang" cam be a string (id) or a Language entry +Langs.prototype.isDefault = function(lang) { + lang = lang.id || lang; + return (this.cound() > 0 && this.getDefault().id == lang); +}; + // Return the count of languages Langs.prototype.count = function() { - return this.languages.length; + return _.size(this.languages); }; module.exports = Langs; diff --git a/lib/book.js b/lib/book.js index 77539ce..73a43ec 100644 --- a/lib/book.js +++ b/lib/book.js @@ -97,9 +97,27 @@ Book.prototype.prepareConfig = function() { }; // Resolve a path in the book source -// Enforce that the output path in the root folder +// Enforce that the output path is in the scope Book.prototype.resolve = function() { - return pathUtil.resolveInRoot.apply(null, [this.root].concat(_.toArray(arguments))); + var filename = path.resolve.apply([this.root].concat(_.toArray(arguments))); + if (!this.isFileInScope(filename)) { + var err = new Error('EACCESS: "' + filename + '" not in "' + this.root + '"'); + err.code = 'EACCESS'; + throw err; + } + + return filename; +}; + +// Return false if a file is outside the book' scope +Book.prototype.isFileInScope = function(filename) { + filename = path.resolve(this.root, filename); + + // Is the file in the scope of the parent? + if (this.parent && this.parent.isFileInScope(filename)) return true; + + // Is file in the root folder? + return pathUtil.isInRoot(this.root, filename); }; // Parse .gitignore, etc to extract rules @@ -133,8 +151,25 @@ Book.prototype.parse = function() { .then(function() { if (that.isMultilingual()) { + if (that.isLanguageBook()) { + throw new Error('A multilingual book as a language book is forbidden'); + } + that.log.info.ln('Parsing multilingual book, with', that.langs.count(), 'languages'); - return; + + // Create a new book for each language and parse it + return Promise.serial(that.langs.list(), function(lang) { + that.log.debug.ln('Preparing book for language', lang.id); + var langBook = new Book({ + fs: that.fs, + parent: that, + root: that.resolve(lang.id) + }); + + that.books.push(langBook); + + return langBook.parse(); + }); } return Promise() @@ -229,4 +264,14 @@ Book.prototype.isMultilingual = function() { return this.langs.count() > 0; }; +// Return true if file is in the scope of a child book +Book.prototype.isInLanguageBook = function(filename) { + return _.some(this.langs.list(), function(lang) { + return pathUtil.isInRoot( + this.resolve(lang.id), + this.resolve(filename) + ); + }); +}; + module.exports = Book; diff --git a/lib/output.js b/lib/output.js index 2e5bc65..d09f29d 100644 --- a/lib/output.js +++ b/lib/output.js @@ -19,6 +19,7 @@ Output.prototype.writeFile = function(filename, buf) { // Start the generation, for a parsed book Output.prototype.generate = function() { var that = this; + var isMultilingual = this.isMultilingual(); return Promise() @@ -33,9 +34,11 @@ Output.prototype.generate = function() { }) .then(function(files) { return Promise.serie(files, function(filename) { - var isPage = that.book.hasPage(filename); + // Ignore file present in a language book + if (isMultilingual && that.book.isInLanguageBook(filename)) return; - if (isPage) { + // Process file as page or asset + if (that.book.hasPage(filename)) { return that.generator.writePage(that.book.getPage(filename)); } else { return that.generator.writeAsset(filename); |