summaryrefslogtreecommitdiffstats
path: root/lib/backbone
diff options
context:
space:
mode:
Diffstat (limited to 'lib/backbone')
-rw-r--r--lib/backbone/summary.js103
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;