diff options
Diffstat (limited to 'lib/backbone/summary.js')
-rw-r--r-- | lib/backbone/summary.js | 103 |
1 files changed, 84 insertions, 19 deletions
diff --git a/lib/backbone/summary.js b/lib/backbone/summary.js index 8e1a66d..d9253a7 100644 --- a/lib/backbone/summary.js +++ b/lib/backbone/summary.js @@ -20,7 +20,11 @@ function TOCArticle(def, parent) { // As string indicating the overall position // ex: '1.0.0' - this.level = def.level; + this.level; + + // When README has been automatically added + this.isAutoIntro = def.isAutoIntro; + this.isIntroduction = def.isIntroduction; if (!def.title) { throw error.ParsingError(new Error('SUMMARY entries should have an non-empty title')); @@ -41,10 +45,16 @@ function TOCArticle(def, parent) { } // Iterate over all articles in this articles -TOCArticle.prototype.walk = function(iter) { - _.each(this.articles, function(article) { - iter(article); - article.walk(iter); +TOCArticle.prototype.walk = function(iter, base) { + base = base || this.level; + + _.each(this.articles, function(article, i) { + var level = levelId(base, i); + + if (iter(article, level) === false) { + return false; + } + article.walk(iter, level); }); }; @@ -69,6 +79,11 @@ TOCArticle.prototype.isExternal = function() { return location.isExternal(this.ref); }; +// Return true if this article is the introduction +TOCArticle.prototype.isIntro = function() { + return Boolean(this.isIntroduction); +}; + // Return true if has children TOCArticle.prototype.hasChildren = function() { return this.articles.length > 0; @@ -147,19 +162,37 @@ TOCArticle.prototype.map = function(iter) { A part of a ToC is a composed of a tree of articles. */ function TOCPart(part) { + if (!(this instanceof TOCPart)) return new TOCPart(part); + this.articles = _.map(part.articles || part.chapters, function(article) { return new TOCArticle(article, this); }, this); } // Iterate over all entries of the part -TOCPart.prototype.walk = function(iter) { - _.each(this.articles, function(article) { - if (iter(article) === false) { +TOCPart.prototype.walk = function(iter, base) { + var articles = this.articles; + + if (articles.length == 0) return; + + // Has introduction? + if (articles[0].isIntro()) { + if (iter(articles[0], '0') === false) { + return; + } + + articles = articles.slice(1); + } + + + _.each(articles, function(article, i) { + var level = levelId(base, i); + + if (iter(article, level) === false) { return false; } - article.walk(iter); + article.walk(iter, level); }); }; @@ -187,15 +220,27 @@ Summary.prototype.parse = function(content) { return this.parser.summary(content) - // TODO: update GitBook's parsers to return a list of parts - .then(function(part) { - that.parts = [new TOCPart(part)]; + .then(function(summary) { + that.parts = _.map(summary.parts, TOCPart); + + // Create first part if none + if (that.parts.length == 0) { + that.parts.push(new TOCPart([])); + } - // Update count of articles - that._length = 0; - that.walk(function() { - that._length += 1; - }); + // Add README as first entry + var firstArticle = that.parts[0].articles[0]; + if (!firstArticle || firstArticle.path != that.book.readme.path) { + that.parts[0].articles.unshift(new TOCArticle({ + title: 'Introduction', + path: that.book.readme.path, + isAutoIntro: true + }, that.parts[0])); + } + that.parts[0].articles[0].isIntroduction = true; + + // Update count of articles and create "level" + that.update(); }); }; @@ -224,8 +269,10 @@ Summary.prototype.getContext = function() { // Iterate over all entries of the summary // iter is called with an TOCArticle Summary.prototype.walk = function(iter) { - _.each(this.parts, function(part) { - part.walk(iter); + var hasMultipleParts = this.parts.length > 1; + + _.each(this.parts, function(part, i) { + part.walk(iter, hasMultipleParts? levelId('', i) : null); }); }; @@ -264,4 +311,22 @@ Summary.prototype.count = function() { return this._length; }; +// Update the count and indexing of "level" +Summary.prototype.update = function() { + var that = this; + + that._length = 0; + that.walk(function(article, level) { + article.level = level; + that._length += 1; + }); +}; + + +// Return a level string from a base level and an index +function levelId(base, i) { + i = i + 1; + return (base? [base || '', i] : [i]).join('.'); +} + module.exports = Summary; |